diff --git a/.github/workflows/deploy_pietervdvn.yml b/.github/workflows/deploy_pietervdvn.yml index 54b89561a..dfa564468 100644 --- a/.github/workflows/deploy_pietervdvn.yml +++ b/.github/workflows/deploy_pietervdvn.yml @@ -11,7 +11,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1.2.0 with: - node-version: '15' + node-version: '16' env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' diff --git a/.github/workflows/pull_request_check.yml b/.github/workflows/pull_request_check.yml deleted file mode 100644 index 27165f776..000000000 --- a/.github/workflows/pull_request_check.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Pull request check -on: - pull_request_target: - types: [ opened, edited, synchronize, ready_for_review, review_requested ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - uses: actions/checkout@v2 - - name: Set up Node.js - uses: actions/setup-node@v1.2.0 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - - - name: install deps - run: npm ci - - - name: create generated dir - run: mkdir ./assets/generated - - - name: create stub themes - run: "echo '{\"layers\": [], \"themes\": []}' > ./assets/generated/known_layers_and_themes.json" - - - name: generate assets - run: npm run generate:images - - - name: generate translations - run: npm run generate:translations - - - name: Compile license info - run: npm run generate:licenses - - - name: Compile and validate themes and layers - run: npm run validate:layeroverview - - - name: Validate license info - run: npm run validate:licenses - - - name: Set failure key - run: | - ls - if [[ -f "layer_report.txt" || -f "missing_licenses.txt" ]]; then - echo "Found a report..." - echo "VALIDATION_FAILED=true" >> $GITHUB_ENV - else - echo "VALIDATION_FAILED=false" >> $GITHUB_ENV - fi - - - name: Test variable - run: echo "${{ env.VALIDATION_FAILED }}" - - - name: Archive reports - uses: actions/upload-artifact@v2 - if: >- - env.VALIDATION_FAILED == 'true' - with: - name: reports - path: | - layer_report.txt - missing_licenses.txt - - - name: Comment PR - uses: allthatjazzleo/actions-pull-request-add-comment@master - if: >- - env.VALIDATION_FAILED == 'true' - with: - message: "cat layer_report.txt missing_licenses.txt" - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/theme_validation_and_deploy.yml b/.github/workflows/theme_validation_and_deploy.yml index 06c0b7fdf..fd7efe0d8 100644 --- a/.github/workflows/theme_validation_and_deploy.yml +++ b/.github/workflows/theme_validation_and_deploy.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1.2.0 with: - node-version: '15' + node-version: '16' env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 35cfb010c..57dbbf0ba 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -1,6 +1,7 @@ import AllKnownLayers from "./AllKnownLayers"; import * as known_themes from "../assets/generated/known_layers_and_themes.json" import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; +import LayerConfig from "../Models/ThemeConfig/LayerConfig"; export class AllKnownLayouts { @@ -8,6 +9,26 @@ export class AllKnownLayouts { public static allKnownLayouts: Map = AllKnownLayouts.AllLayouts(); public static layoutsList: LayoutConfig[] = AllKnownLayouts.GenerateOrderedList(AllKnownLayouts.allKnownLayouts); + public static AllPublicLayers(){ + const allLayers : LayerConfig[] = [] + const seendIds = new Set() + const publicLayouts = AllKnownLayouts.layoutsList.filter(l => !l.hideFromOverview) + for (const layout of publicLayouts) { + if(layout.hideFromOverview){ + continue + } + for (const layer of layout.layers) { + if(seendIds.has(layer.id)){ + continue + } + seendIds.add(layer.id) + allLayers.push(layer) + } + + } + return allLayers + } + private static GenerateOrderedList(allKnownLayouts: Map): LayoutConfig[] { const keys = ["personal", "cyclofix", "hailhydrant", "bookcases", "toilets", "aed"] const list = [] diff --git a/Docs/Development_deployment.md b/Docs/Development_deployment.md index 292f3f994..aceae49e7 100644 --- a/Docs/Development_deployment.md +++ b/Docs/Development_deployment.md @@ -31,7 +31,7 @@ To develop and build MapComplete, you - You can [use asdf to manage your runtime versions](https://asdf-vm.com/). 0. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install nodeJS: https://nodejs.org/en/download/ -0. Install `wget`, `brew install wget` +0. On iOS, install `wget` (`brew install wget`) 0. Run `npm run init` which … - runs `npm install` - generates some additional dependencies and files diff --git a/Docs/Release_Notes.md b/Docs/Release_Notes.md index ea1b1ded2..c6f0ac35d 100644 --- a/Docs/Release_Notes.md +++ b/Docs/Release_Notes.md @@ -3,6 +3,41 @@ Release Notes Some highlights of new releases. +0.10 +---- + +The 0.10 version contains a lot of refactorings on various core of the application, namely in the rendering stack, the fetching of data and uploading. + +Some highlights are: + +1. The addition of fallback overpass servers +2. Fetching data from OSM directly (especially useful in the personal theme) +3. Splitting all the features per tile (with a maximum amount of features per tile, splitting further if needed), making everything a ton faster +4. If a tile has too much features, the featuers are not shown. Instead, a rectangle with the feature amount is shown. + +Furthermore, it contains a few new themes and theme updates: + +- Restaurants and fast food +- Pubs and cafés +- Charging stations got a major overhaul - thanks for all the input on the available plugs +- Observation towers and binoculars +- The addition of a hackerspace theme (as made on SOTM) + +Other various small improvements: + +- The filter state is now exposed in the URL, so can be shared +- Lots of other fixes, as usual + +0.8 and 0.9 +----------- + +Addition of filters per layer +Addition of a download-as-pdf for select themes +Addition of a download-as-geojson and download-as-csv for select themes + +... + + 0.7.0 ----- diff --git a/Docs/Tools/GenerateSeries.ts b/Docs/Tools/GenerateSeries.ts index 5cced5a6b..73e97e9a4 100644 --- a/Docs/Tools/GenerateSeries.ts +++ b/Docs/Tools/GenerateSeries.ts @@ -75,9 +75,7 @@ class StatsDownloader { while (url) { ScriptUtils.erasableLog(`Downloading stats for ${year}-${month}, page ${page} ${url}`) - const result = await ScriptUtils.DownloadJSON(url, { - headers: headers - }) + const result = await ScriptUtils.DownloadJSON(url, headers) page++; allFeatures.push(...result.features) if (result.features === undefined) { diff --git a/Docs/wikiIndex.txt b/Docs/wikiIndex.txt index f9d8ab6da..4bd9edfad 100644 --- a/Docs/wikiIndex.txt +++ b/Docs/wikiIndex.txt @@ -4,8 +4,8 @@ {{service_item |name= [https://mapcomplete.osm.be/personal personal] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:gl|en}}, {{#language:de|en}} -|descr= A MapComplete theme: Create a personal theme based on all the available layers of all themes +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:gl|en}}, {{#language:fr|en}}, {{#language:de|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: Create a personal theme based on all the available layers of all themes. In order to show some data, open [[#filter]] |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, personal @@ -13,25 +13,29 @@ {{service_item |name= [https://mapcomplete.osm.be/cyclofix cyclofix] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:gl|en}}, {{#language:de|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:gl|en}}, {{#language:de|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}} |descr= A MapComplete theme: The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.

You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.

All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.

For more information about the cyclofix project, go to [[https://cyclofix.osm.be/]]. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, cyclofix }} {{service_item -|name= [https://mapcomplete.osm.be/aed aed] +|name= [https://mapcomplete.osm.be/hailhydrant hailhydrant] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:de|en}} -|descr= A MapComplete theme: On this map, one can find and mark nearby defibrillators -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|lang= {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}}, {{#language:fr|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map you can find and update hydrants, fire stations, ambulance stations, and extinguishers in your favorite neighborhoods. + +You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide additional details by answering available questions. + +All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Erwin Olario;]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, aed +|genre= POI, editor, hailhydrant }} {{service_item |name= [https://mapcomplete.osm.be/bookcases bookcases] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:pt_BR|en}} |descr= A MapComplete theme: A public bookcase is a small streetside cabinet, box, old phone boot or some other objects where books are stored. Everyone can place or take a book. This map aims to collect all these bookcases. You can discover new bookcases nearby and, with a free OpenStreetMap account, quickly add your favourite bookcases. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png @@ -40,47 +44,173 @@ {{service_item |name= [https://mapcomplete.osm.be/toilets toilets] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}} +|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:pl|en}} |descr= A MapComplete theme: A map of public toilets |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, toilets }} {{service_item -|name= [https://mapcomplete.osm.be/artworks artworks] +|name= [https://mapcomplete.osm.be/aed aed] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:de|en}} -|descr= A MapComplete theme: Welcome to Open Artwork Map, a map of statues, busts, grafittis, ... all over the world +|lang= {{#language:en|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:sv|en}}, {{#language:pl|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: On this map, one can find and mark nearby defibrillators |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, artworks +|genre= POI, editor, aed +}} +{{service_item +|name= [https://mapcomplete.osm.be/artwork artwork] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:sv|en}}, {{#language:pl|en}}, {{#language:es|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: Welcome to Open Artwork Map, a map of statues, busts, grafittis and other artwork all over the world +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, artwork +}} +{{service_item +|name= [https://mapcomplete.osm.be/benches benches] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Florian Edelmann;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, benches +}} +{{service_item +|name= [https://mapcomplete.osm.be/bicyclelib bicyclelib] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:de|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, bicyclelib +}} +{{service_item +|name= [https://mapcomplete.osm.be/binoculars binoculars] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, binoculars +}} +{{service_item +|name= [https://mapcomplete.osm.be/cafes_and_pubs cafes_and_pubs] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}} +|descr= A MapComplete theme: Cafés, kroegen en drinkgelegenheden +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cafes_and_pubs +}} +{{service_item +|name= [https://mapcomplete.osm.be/campersite campersite] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:pt_BR|en}}, {{#language:id|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, campersite +}} +{{service_item +|name= [https://mapcomplete.osm.be/charging_stations charging_stations] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ja|en}}, {{#language:ru|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:nl|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: On this open map, one can find and mark information about charging stations +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, charging_stations +}} +{{service_item +|name= [https://mapcomplete.osm.be/climbing climbing] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:de|en}}, {{#language:en|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:ca|en}}, {{#language:fr|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Christian Neumann ;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, climbing +}} +{{service_item +|name= [https://mapcomplete.osm.be/cycle_infra cycle_infra] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map where you can view and edit things related to the bicycle infrastructure. Made during #osoc21. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cycle_infra +}} +{{service_item +|name= [https://mapcomplete.osm.be/cyclestreets cyclestreets] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: A cyclestreet is is a street where motorized traffic is not allowed to overtake cyclists. They are signposted by a special traffic sign. Cyclestreets can be found in the Netherlands and Belgium, but also in Germany and France. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cyclestreets +}} +{{service_item +|name= [https://mapcomplete.osm.be/drinking_water drinking_water] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}} +|descr= A MapComplete theme: On this map, publicly accessible drinking water spots are shown and can be easily added +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, drinking_water +}} +{{service_item +|name= [https://mapcomplete.osm.be/facadegardens facadegardens] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:fr|en}}, {{#language:nb_NO|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: [[https://nl.wikipedia.org/wiki/Geveltuin' target=_blank>Facade gardens, green facades and trees in the city not only bring peace and quiet, but also a more beautiful city, greater biodiversity, a cooling effect and better air quality.
Klimaan VZW and Mechelen Klimaatneutraal want to map existing and new facade gardens as an example for people who want to build their own garden or for city walkers who love nature.
More info about the project at klimaan.be. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe; stla;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, facadegardens +}} +{{service_item +|name= [https://mapcomplete.osm.be/food food] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}} +|descr= A MapComplete theme: Restaurants en fast food +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, food +}} +{{service_item +|name= [https://mapcomplete.osm.be/fritures fritures] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:ca|en}}, {{#language:id|en}}, {{#language:ru|en}}, {{#language:it|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: Op deze kaart vind je je favoriete frituur! +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, fritures }} {{service_item |name= [https://mapcomplete.osm.be/ghostbikes ghostbikes] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:ja|en}}, {{#language:nb_NO|en}}, {{#language:zh_Hant|en}}, {{#language:fr|en}}, {{#language:eo|en}}, {{#language:es|en}}, {{#language:fi|en}}, {{#language:gl|en}}, {{#language:hu|en}}, {{#language:it|en}}, {{#language:pl|en}}, {{#language:pt_BR|en}}, {{#language:ru|en}}, {{#language:sv|en}} |descr= A MapComplete theme: A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.

On this map, one can see all the ghost bikes which are known by OpenStreetMap. Is a ghost bike missing? Everyone can add or update information here - you only need to have a (free) OpenStreetMap account. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, ghostbikes }} {{service_item -|name= [https://mapcomplete.osm.be/shops shops] +|name= [https://mapcomplete.osm.be/hackerspaces hackerspaces] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: On this map, one can mark basic information about shops, add opening hours and phone numbers +|lang= {{#language:en|en}} +|descr= A MapComplete theme: On this map you can see hackerspaces, add a new hackerspace or update data directly |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, shops +|genre= POI, editor, hackerspaces }} {{service_item -|name= [https://mapcomplete.osm.be/drinking_water drinking_water] +|name= [https://mapcomplete.osm.be/maps maps] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: On this map, publicly accessible drinkging water spots are shown and can be easily added +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: On this map you can find all maps OpenStreetMap knows - typically a big map on an information board showing the area, city or region, e.g. a tourist map on the back of a billboard, a map of a nature reserve, a map of cycling networks in the region, ...)

If a map is missing, you can easily map this map on OpenStreetMap. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, drinking_water +|genre= POI, editor, maps }} {{service_item |name= [https://mapcomplete.osm.be/nature nature] @@ -92,111 +222,93 @@ |genre= POI, editor, nature }} {{service_item -|name= [https://mapcomplete.osm.be/fietsstraten fietsstraten] -|region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Een fietsstraat is een straat waar
  • automobilisten geen fietsers mogen inhalen
  • Er een maximumsnelheid van 30km/u geldt
  • Fietsers gemotoriseerde voortuigen links mogen inhalen
  • Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad


Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau. -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, fietsstraten -}} -{{service_item -|name= [https://mapcomplete.osm.be/bicyclelib bicyclelib] +|name= [https://mapcomplete.osm.be/observation_towers observation_towers] |region= Worldwide |lang= {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike +|descr= A MapComplete theme: Publicly accessible towers to enjoy the view |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, bicyclelib +|genre= POI, editor, observation_towers }} {{service_item -|name= [https://mapcomplete.osm.be/maps maps] +|name= [https://mapcomplete.osm.be/openwindpowermap openwindpowermap] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: On this map you can find all maps OpenStreetMap knows - typically a big map on an information board showing the area, city or region, e.g. a tourist map on the back of a billboard, a map of a nature reserve, a map of cycling networks in the region, ...)

If a map is missing, you can easily map this map on OpenStreetMap. +|lang= {{#language:en|en}}, {{#language:fr|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map for showing and editing wind turbines. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Seppe Santens;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, openwindpowermap +}} +{{service_item +|name= [https://mapcomplete.osm.be/parkings parkings] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}} +|descr= A MapComplete theme: This map shows different parking spots |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, maps +|genre= POI, editor, parkings }} {{service_item -|name= [https://mapcomplete.osm.be/fritures fritures] +|name= [https://mapcomplete.osm.be/playgrounds playgrounds] |region= Worldwide -|lang= {{#language:nl|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: Op deze kaart vind je je favoriete frituur! +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: On this map, you find playgrounds and can add more information |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, fritures +|genre= POI, editor, playgrounds }} {{service_item -|name= [https://mapcomplete.osm.be/benches benches] +|name= [https://mapcomplete.osm.be/shops shops] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Florian Edelmann;]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, benches -}} -{{service_item -|name= [https://mapcomplete.osm.be/charging_stations charging_stations] -|region= Worldwide -|lang= {{#language:en|en}} -|descr= A MapComplete theme: On this open map, one can find and mark information about charging stations +|lang= {{#language:en|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}}, {{#language:nl|en}}, {{#language:ca|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map, one can mark basic information about shops, add opening hours and phone numbers |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, charging_stations +|genre= POI, editor, shops +}} +{{service_item +|name= [https://mapcomplete.osm.be/sport_pitches sport_pitches] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: A sport pitch is an area where sports are played +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, sport_pitches }} {{service_item |name= [https://mapcomplete.osm.be/surveillance surveillance] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:fr|en}}, {{#language:pl|en}} |descr= A MapComplete theme: On this open map, you can find surveillance cameras. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, surveillance }} {{service_item -|name= [https://mapcomplete.osm.be/climbing climbing] -|region= Worldwide -|lang= {{#language:de|en}}, {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Christian Neumann ;]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, climbing -}} -{{service_item -|name= [https://mapcomplete.osm.be/playgrounds playgrounds] -|region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Op deze kaart vind je speelplekken zoals speeltuinen, speelbossen en sportterreinen -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, playgrounds -}} -{{service_item |name= [https://mapcomplete.osm.be/trees trees] |region= Worldwide -|lang= {{#language:nl|en}}, {{#language:en|en}} +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:fr|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:pl|en}} |descr= A MapComplete theme: Map all the trees! |material= {{yes|[https://mapcomplete.osm.be/ Yes, by Midgard;]}} |image= MapComplete_Screenshot.png |genre= POI, editor, trees }} {{service_item -|name= [https://mapcomplete.osm.be/campersite campersite] +|name= [https://mapcomplete.osm.be/uk_addresses uk_addresses] |region= Worldwide |lang= {{#language:en|en}} -|descr= A MapComplete theme: This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe;]}} +|descr= A MapComplete theme: Contribute to OpenStreetMap by filling out address information +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Pieter Vander Vennet, Rob Nickerson, Russ Garrett;]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, campersite +|genre= POI, editor, uk_addresses }} {{service_item -|name= [https://mapcomplete.osm.be/sport_pitches sport_pitches] +|name= [https://mapcomplete.osm.be/waste_basket waste_basket] |region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Een sportveld is een ingerichte plaats met infrastructuur om een sport te beoefenen +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: On this map, you'll find waste baskets near you. If a waste basket is missing on this map, you can add it yourself |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, sport_pitches +|genre= POI, editor, waste_basket }} |} \ No newline at end of file diff --git a/InitUiElements.ts b/InitUiElements.ts index 3f591a3d1..d0eb8b0d4 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -15,7 +15,6 @@ import Link from "./UI/Base/Link"; import * as personal from "./assets/themes/personal/personal.json"; import * as L from "leaflet"; import Img from "./UI/Base/Img"; -import UserDetails from "./Logic/Osm/OsmConnection"; import Attribution from "./UI/BigComponents/Attribution"; import BackgroundLayerResetter from "./Logic/Actors/BackgroundLayerResetter"; import FullWelcomePaneWithTabs from "./UI/BigComponents/FullWelcomePaneWithTabs"; @@ -26,16 +25,22 @@ import ScrollableFullScreen from "./UI/Base/ScrollableFullScreen"; import Translations from "./UI/i18n/Translations"; import MapControlButton from "./UI/MapControlButton"; import LZString from "lz-string"; -import AllKnownLayers from "./Customizations/AllKnownLayers"; import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; -import {TagsFilter} from "./Logic/Tags/TagsFilter"; import LeftControls from "./UI/BigComponents/LeftControls"; import RightControls from "./UI/BigComponents/RightControls"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; -import LayerConfig from "./Models/ThemeConfig/LayerConfig"; import Minimap from "./UI/Base/Minimap"; import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler"; +import Combine from "./UI/Base/Combine"; +import {SubtleButton} from "./UI/Base/SubtleButton"; +import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; +import {Tiles} from "./Models/TileRange"; +import {TileHierarchyAggregator} from "./UI/ShowDataLayer/TileHierarchyAggregator"; +import FilterConfig from "./Models/ThemeConfig/FilterConfig"; +import FilteredLayer from "./Models/FilteredLayer"; +import {BBox} from "./Logic/BBox"; +import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; export class InitUiElements { static InitAll( @@ -62,10 +67,24 @@ export class InitUiElements { "LayoutFromBase64 is ", layoutFromBase64 ); + + if(layoutToUse.id === personal.id){ + layoutToUse.layers = AllKnownLayouts.AllPublicLayers() + for (const layer of layoutToUse.layers) { + layer.minzoomVisible = Math.max(layer.minzoomVisible, layer.minzoom) + layer.minzoom = Math.max(16, layer.minzoom) + } + } State.state = new State(layoutToUse); - // This 'leaks' the global state via the window object, useful for debugging + if(layoutToUse.id === personal.id) { + // Disable overpass all together + State.state.overpassMaxZoom.setData(0) + + } + + // This 'leaks' the global state via the window object, useful for debugging // @ts-ignore window.mapcomplete_state = State.state; @@ -94,45 +113,6 @@ export class InitUiElements { } } - function updateFavs() { - // This is purely for the personal theme to load the layers there - const favs = State.state.favouriteLayers.data ?? []; - - const neededLayers = new Set(); - - console.log("Favourites are: ", favs); - layoutToUse.layers.splice(0, layoutToUse.layers.length); - let somethingChanged = false; - for (const fav of favs) { - if (AllKnownLayers.sharedLayers.has(fav)) { - const layer = AllKnownLayers.sharedLayers.get(fav); - if (!neededLayers.has(layer)) { - neededLayers.add(layer); - somethingChanged = true; - } - } - - for (const layouts of State.state.installedThemes.data) { - for (const layer of layouts.layout.layers) { - if (typeof layer === "string") { - continue; - } - if (layer.id === fav) { - if (!neededLayers.has(layer)) { - neededLayers.add(layer); - somethingChanged = true; - } - } - } - } - } - if (somethingChanged) { - State.state.layoutToUse.data.layers = Array.from(neededLayers); - State.state.layoutToUse.ping(); - State.state.featurePipeline?.ForceRefresh(); - } - } - if (layoutToUse.customCss !== undefined) { Utils.LoadCustomCss(layoutToUse.customCss); } @@ -165,35 +145,42 @@ export class InitUiElements { ).AttachTo("messagesbox"); } - State.state.osmConnection.userDetails - .map((userDetails: UserDetails) => userDetails?.home) - .addCallbackAndRunD((home) => { - const color = getComputedStyle(document.body).getPropertyValue( - "--subtle-detail-color" - ); - const icon = L.icon({ - iconUrl: Img.AsData( - Svg.home_white_bg.replace(/#ffffff/g, color) - ), - iconSize: [30, 30], - iconAnchor: [15, 15], - }); - const marker = L.marker([home.lat, home.lon], {icon: icon}); - marker.addTo(State.state.leafletMap.data); + function addHomeMarker() { + const userDetails = State.state.osmConnection.userDetails.data; + if (userDetails === undefined) { + return false; + } + console.log("Adding home location of ", userDetails) + const home = userDetails.home; + if (home === undefined) { + return userDetails.loggedIn; // If logged in, the home is not set and we unregister. If not logged in, we stay registered if a login still comes + } + const leaflet = State.state.leafletMap.data; + if (leaflet === undefined) { + return false; + } + const color = getComputedStyle(document.body).getPropertyValue( + "--subtle-detail-color" + ); + const icon = L.icon({ + iconUrl: Img.AsData( + Svg.home_white_bg.replace(/#ffffff/g, color) + ), + iconSize: [30, 30], + iconAnchor: [15, 15], }); - - if (layoutToUse.id === personal.id) { - updateFavs(); + const marker = L.marker([home.lat, home.lon], {icon: icon}); + marker.addTo(leaflet); + return true; } + State.state.osmConnection.userDetails + .addCallbackAndRunD(_ => addHomeMarker()); + State.state.leafletMap.addCallbackAndRunD(_ => addHomeMarker()) + + InitUiElements.setupAllLayerElements(); - - if (layoutToUse.id === personal.id) { - State.state.favouriteLayers.addCallback(updateFavs); - State.state.installedThemes.addCallback(updateFavs); - } else { State.state.locationControl.ping(); - } new SelectedFeatureHandler(Hash.hash, State.state) @@ -207,8 +194,8 @@ export class InitUiElements { static LoadLayoutFromHash( userLayoutParam: UIEventSource ): [LayoutConfig, string] { + let hash = location.hash.substr(1); try { - let hash = location.hash.substr(1); const layoutFromBase64 = userLayoutParam.data; // layoutFromBase64 contains the name of the theme. This is partly to do tracking with goat counter @@ -247,9 +234,21 @@ export class InitUiElements { userLayoutParam.setData(layoutToUse.id); return [layoutToUse, btoa(Utils.MinifyJSON(JSON.stringify(json)))]; } catch (e) { - new FixedUiElement( - "Error: could not parse the custom layout:
" + e - ).AttachTo("centermessage"); + + if (hash === undefined || hash.length < 10) { + e = "Did you effectively add a theme? It seems no data could be found." + } + + new Combine([ + "Error: could not parse the custom layout:", + new FixedUiElement("" + e).SetClass("alert"), + new SubtleButton("./assets/svg/mapcomplete_logo.svg", + "Go back to the theme overview", + {url: window.location.protocol + "//" + window.location.hostname + "/index.html", newTab: false}) + + ]) + .SetClass("flex flex-col") + .AttachTo("centermessage"); throw e; } } @@ -322,9 +321,7 @@ export class InitUiElements { State.state.backgroundLayer, State.state.locationControl, State.state.availableBackgroundLayers, - State.state.layoutToUse.map( - (layout: LayoutConfig) => layout.defaultBackgroundId - ) + State.state.layoutToUse.defaultBackgroundId ); const attr = new Attribution( @@ -344,15 +341,15 @@ export class InitUiElements { }).SetClass("w-full h-full") .AttachTo("leafletDiv") - const layout = State.state.layoutToUse.data; + const layout = State.state.layoutToUse; if (layout.lockLocation) { if (layout.lockLocation === true) { - const tile = Utils.embedded_tile( + const tile = Tiles.embedded_tile( layout.startLat, layout.startLon, layout.startZoom - 1 ); - const bounds = Utils.tile_bounds(tile.z, tile.x, tile.y); + const bounds = Tiles.tile_bounds(tile.z, tile.x, tile.y); // We use the bounds to get a sense of distance for this zoom level const latDiff = bounds[0][0] - bounds[1][0]; const lonDiff = bounds[0][1] - bounds[1][1]; @@ -372,41 +369,137 @@ export class InitUiElements { private static InitLayers(): void { const state = State.state; - state.filteredLayers = state.layoutToUse.map((layoutToUse) => { - const flayers = []; + const empty = [] - for (const layer of layoutToUse.layers) { - const isDisplayed = QueryParameters.GetQueryParameter( + const flayers: FilteredLayer[] = []; + + for (const layer of state.layoutToUse.layers) { + let defaultShown = "true" + if(state.layoutToUse.id === personal.id){ + defaultShown = "false" + } + + let isDisplayed: UIEventSource + if(state.layoutToUse.id === personal.id){ + isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") + .map(value => value === "yes", [], enabled => { + return enabled ? "yes" : ""; + }) + isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) + }else{ + isDisplayed = QueryParameters.GetQueryParameter( "layer-" + layer.id, - "true", + defaultShown, "Wether or not layer " + layer.id + " is shown" ).map( (str) => str !== "false", [], (b) => b.toString() ); - const flayer = { - isDisplayed: isDisplayed, - layerDef: layer, - appliedFilters: new UIEventSource(undefined), - }; - flayers.push(flayer); } - return flayers; - }); + const flayer = { + isDisplayed: isDisplayed, + layerDef: layer, + appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), + }; + + if (layer.filters.length > 0) { + const filtersPerName = new Map() + layer.filters.forEach(f => filtersPerName.set(f.id, f)) + const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") + flayer.appliedFilters.map(filters => { + filters = filters ?? [] + return filters.map(f => f.filter.id + "." + f.selected).join(",") + }, [], textual => { + if(textual.length === 0){ + return empty + } + return textual.split(",").map(part => { + const [filterId, selected] = part.split("."); + return {filter: filtersPerName.get(filterId), selected: Number(selected)} + }).filter(f => f.filter !== undefined && !isNaN(f.selected)) + }).syncWith(qp, true) + } + + flayers.push(flayer); + } + state.filteredLayers = new UIEventSource(flayers); + + + + + const clusterCounter = TileHierarchyAggregator.createHierarchy() + new ShowDataLayer({ + features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements), + leafletMap: State.state.leafletMap, + layerToShow: ShowTileInfo.styling, + enablePopups: false + }) State.state.featurePipeline = new FeaturePipeline( source => { + + clusterCounter.addTile(source) + + const clustering = State.state.layoutToUse.clustering + const doShowFeatures = source.features.map( + f => { + const z = State.state.locationControl.data.zoom + + if(!source.layer.isDisplayed.data){ + return false; + } + + if (z < source.layer.layerDef.minzoom) { + // Layer is always hidden for this zoom level + return false; + } + + if (z >= clustering.maxZoom) { + return true + } + + if (f.length > clustering.minNeededElements) { + // This tile alone already has too much features + return false + } + + let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex); + if (tileZ >= z) { + + while (tileZ > z) { + tileZ-- + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + } + + if (clusterCounter.getTile(Tiles.tile_index(tileZ, tileX, tileY))?.totalValue > clustering.minNeededElements) { + return false + } + } + + + const bounds = State.state.currentBounds.data + const tilebbox = BBox.fromTileIndex(source.tileIndex) + if (!tilebbox.overlapsWith(bounds)) { + // Not within range + return false + } + + return true + }, [State.state.currentBounds] + ) + new ShowDataLayer( { features: source, leafletMap: State.state.leafletMap, - layerToShow: source.layer.layerDef + layerToShow: source.layer.layerDef, + doShowLayer: doShowFeatures } ); }, state ); - } private static setupAllLayerElements() { diff --git a/Logic/Actors/BackgroundLayerResetter.ts b/Logic/Actors/BackgroundLayerResetter.ts index 96c43bda3..d193d8132 100644 --- a/Logic/Actors/BackgroundLayerResetter.ts +++ b/Logic/Actors/BackgroundLayerResetter.ts @@ -11,8 +11,8 @@ export default class BackgroundLayerResetter { constructor(currentBackgroundLayer: UIEventSource, location: UIEventSource, availableLayers: UIEventSource, - defaultLayerId: UIEventSource = undefined) { - defaultLayerId = defaultLayerId ?? new UIEventSource(AvailableBaseLayers.osmCarto.id); + defaultLayerId: string = undefined) { + defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id; // Change the baselayer back to OSM if we go out of the current range of the layer availableLayers.addCallbackAndRun(availableLayers => { @@ -28,7 +28,7 @@ export default class BackgroundLayerResetter { if (availableLayer.min_zoom > location.data.zoom) { break; } - if (availableLayer.id === defaultLayerId.data) { + if (availableLayer.id === defaultLayerId) { defaultLayer = availableLayer; } return; // All good - the current layer still works! diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index 01e09a717..43ce441d7 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -60,12 +60,12 @@ export default class GeoLocationHandler extends VariableUiElement { * @private */ private readonly _previousLocationGrant: UIEventSource; - private readonly _layoutToUse: UIEventSource; + private readonly _layoutToUse: LayoutConfig; constructor( currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>, leafletMap: UIEventSource, - layoutToUse: UIEventSource + layoutToUse: LayoutConfig ) { const hasLocation = currentGPSLocation.map( (location) => location !== undefined @@ -207,6 +207,9 @@ export default class GeoLocationHandler extends VariableUiElement { }); const map = self._leafletMap.data; + if(map === undefined){ + return; + } const newMarker = L.marker(location.latlng, {icon: icon}); newMarker.addTo(map); @@ -264,7 +267,7 @@ export default class GeoLocationHandler extends VariableUiElement { } // We check that the GPS location is not out of bounds - const b = this._layoutToUse.data.lockLocation; + const b = this._layoutToUse.lockLocation; let inRange = true; if (b) { if (b !== true) { diff --git a/Logic/Actors/ImageSearcher.ts b/Logic/Actors/ImageSearcher.ts deleted file mode 100644 index c2d089e51..000000000 --- a/Logic/Actors/ImageSearcher.ts +++ /dev/null @@ -1,173 +0,0 @@ -import {ImagesInCategory, Wikidata, Wikimedia} from "../ImageProviders/Wikimedia"; -import {UIEventSource} from "../UIEventSource"; - -/** - * There are multiple way to fetch images for an object - * 1) There is an image tag - * 2) There is an image tag, the image tag contains multiple ';'-separated URLS - * 3) there are multiple image tags, e.g. 'image', 'image:0', 'image:1', and 'image_0', 'image_1' - however, these are pretty rare so we are gonna ignore them - * 4) There is a wikimedia_commons-tag, which either has a 'File': or a 'category:' containing images - * 5) There is a wikidata-tag, and the wikidata item either has an 'image' attribute or has 'a link to a wikimedia commons category' - * 6) There is a wikipedia article, from which we can deduct the wikidata item - * - * For some images, author and license should be shown - */ -/** - * Class which search for all the possible locations for images and which builds a list of UI-elements for it. - * Note that this list is embedded into an UIEVentSource, ready to put it into a carousel. - * - */ -export class ImageSearcher extends UIEventSource<{ key: string, url: string }[]> { - - private static _cache = new Map(); - private readonly _wdItem = new UIEventSource(""); - private readonly _commons = new UIEventSource(""); - - private constructor(tags: UIEventSource, imagePrefix = "image", loadSpecial = true) { - super([]) - const self = this; - - function AddImages(images: { key: string, url: string }[]) { - const oldUrls = self.data.map(kurl => kurl.url); - let somethingChanged = false; - for (const image of images) { - const url = image.url; - - if (url === undefined || url === null || url === "") { - continue; - } - if (oldUrls.indexOf(url) >= 0) { - // Already exists - continue; - } - - self.data.push(image); - somethingChanged = true; - } - if (somethingChanged) { - self.ping(); - } - } - - function addImage(image: string) { - AddImages([{url: image, key: undefined}]); - } - - - // By wrapping this in a UIEventSource, we prevent multiple queries of loadWikiData - this._wdItem.addCallback(wdItemContents => { - ImageSearcher.loadWikidata(wdItemContents, addImage); - }); - this._commons.addCallback(commonsData => { - ImageSearcher.LoadCommons(commonsData, addImage) - }); - tags.addCallbackAndRun(tags => { - AddImages(ImageSearcher.LoadImages(tags, imagePrefix)); - }); - - if (loadSpecial) { - tags.addCallbackAndRunD(tags => { - - const wdItem = tags.wikidata; - if (wdItem !== undefined) { - self._wdItem.setData(wdItem); - } - const commons = tags.wikimedia_commons; - if (commons !== undefined) { - self._commons.setData(commons); - } - - if (tags.mapillary) { - let mapillary = tags.mapillary; - const prefix = "https://www.mapillary.com/map/im/"; - - let regex = /https?:\/\/www.mapillary.com\/app\/.*pKey=([^&]*).*/ - let match = mapillary.match(regex); - if (match) { - mapillary = match[1]; - } - - if (mapillary.indexOf(prefix) < 0) { - mapillary = prefix + mapillary; - } - - - AddImages([{url: mapillary, key: undefined}]); - } - }) - } - } - - public static construct(tags: UIEventSource, imagePrefix = "image", loadSpecial = true): ImageSearcher { - const key = tags.data["id"] + " " + imagePrefix + loadSpecial; - if (tags.data["id"] !== undefined && ImageSearcher._cache.has(key)) { - return ImageSearcher._cache.get(key) - } - - const searcher = new ImageSearcher(tags, imagePrefix, loadSpecial); - ImageSearcher._cache.set(key, searcher) - return searcher; - } - - private static loadWikidata(wikidataItem, addImage: ((url: string) => void)): void { - // Load the wikidata item, then detect usage on 'commons' - let allWikidataId = wikidataItem.split(";"); - for (let wikidataId of allWikidataId) { - // @ts-ignore - if (wikidataId.startsWith("Q")) { - wikidataId = wikidataId.substr(1); - } - Wikimedia.GetWikiData(parseInt(wikidataId), (wd: Wikidata) => { - addImage(wd.image); - Wikimedia.GetCategoryFiles(wd.commonsWiki, (images: ImagesInCategory) => { - for (const image of images.images) { - if (image.startsWith("File:")) { - addImage(image); - } - } - }) - }) - } - } - - private static LoadCommons(commonsData: string, addImage: ((url: string) => void)): void { - const allCommons: string[] = commonsData.split(";"); - for (const commons of allCommons) { - if (commons.startsWith("Category:")) { - Wikimedia.GetCategoryFiles(commons, (images: ImagesInCategory) => { - for (const image of images.images) { - if (image.startsWith("File:")) { - addImage(image) - } - } - }) - } else { - if (commons.startsWith("File:")) { - addImage(commons) - } - } - } - } - - private static LoadImages(tags: any, imagePrefix: string): { key: string, url: string }[] { - const imageTag = tags[imagePrefix]; - const images: { key: string, url: string }[] = []; - if (imageTag !== undefined) { - const bareImages = imageTag.split(";"); - for (const bareImage of bareImages) { - images.push({key: imagePrefix, url: bareImage}) - } - } - - for (const key in tags) { - if (key.startsWith(imagePrefix + ":")) { - const url = tags[key] - images.push({key: key, url: url}) - } - } - - - return images; - } - -} \ No newline at end of file diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 1e7ace7cd..4f4f7a77f 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -1,17 +1,18 @@ import {UIEventSource} from "../UIEventSource"; -import Loc from "../../Models/Loc"; import {Or} from "../Tags/Or"; import {Overpass} from "../Osm/Overpass"; -import Bounds from "../../Models/Bounds"; -import FeatureSource, {FeatureSourceState} from "../FeatureSource/FeatureSource"; +import FeatureSource from "../FeatureSource/FeatureSource"; import {Utils} from "../../Utils"; import {TagsFilter} from "../Tags/TagsFilter"; import SimpleMetaTagger from "../SimpleMetaTagger"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import RelationsTracker from "../Osm/RelationsTracker"; +import {BBox} from "../BBox"; +import Loc from "../../Models/Loc"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; -export default class OverpassFeatureSource implements FeatureSource, FeatureSourceState { +export default class OverpassFeatureSource implements FeatureSource { public readonly name = "OverpassFeatureSource" @@ -21,124 +22,54 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour public readonly features: UIEventSource<{ feature: any, freshness: Date }[]> = new UIEventSource(undefined); - public readonly sufficientlyZoomed: UIEventSource; public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly timeout: UIEventSource = new UIEventSource(0); - + public readonly relationsTracker: RelationsTracker; - + private readonly retries: UIEventSource = new UIEventSource(0); - /** - * The previous bounds for which the query has been run at the given zoom level - * - * Note that some layers only activate on a certain zoom level. - * If the map location changes, we check for each layer if it is loaded: - * we start checking the bounds at the first zoom level the layer might operate. If in bounds - no reload needed, otherwise we continue walking down - */ - private readonly _previousBounds: Map = new Map(); + private readonly state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, - readonly leafletMap: any, - readonly overpassUrl: UIEventSource; + readonly layoutToUse: LayoutConfig, + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; + readonly currentBounds: UIEventSource } + private readonly _isActive: UIEventSource; + private readonly onBboxLoaded: (bbox: BBox, date: Date, layers: LayerConfig[]) => void; - /** - * The most important layer should go first, as that one gets first pick for the questions - */ constructor( state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, - readonly leafletMap: any, - readonly overpassUrl: UIEventSource; + readonly layoutToUse: LayoutConfig, + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; - readonly overpassMaxZoom: UIEventSource + readonly overpassMaxZoom: UIEventSource, + readonly currentBounds: UIEventSource + }, + options?: { + isActive?: UIEventSource, + relationTracker: RelationsTracker, + onBboxLoaded?: (bbox: BBox, date: Date, layers: LayerConfig[]) => void }) { - this.state = state - this.relationsTracker = new RelationsTracker() - const location = state.locationControl + this._isActive = options.isActive; + this.onBboxLoaded = options.onBboxLoaded + this.relationsTracker = options.relationTracker const self = this; - - this.sufficientlyZoomed = location.map(location => { - if (location?.zoom === undefined) { - return false; - } - let minzoom = Math.min(...state.layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); - if (location.zoom < minzoom) { - return false; - } - const maxZoom = state.overpassMaxZoom.data - if (maxZoom !== undefined && location.zoom > maxZoom) { - return false; - } - - return true; - }, [state.layoutToUse] - ); - for (let i = 0; i < 25; i++) { - // This update removes all data on all layers -> erase the map on lower levels too - this._previousBounds.set(i, []); - } - - state.layoutToUse.addCallback(() => { + state.currentBounds.addCallback(_ => { self.update() - }); - location.addCallback(() => { - self.update() - }); - state.leafletMap.addCallbackAndRunD(_ => { - self.update(); }) + } - public ForceRefresh() { - for (let i = 0; i < 25; i++) { - this._previousBounds.set(i, []); - } - this.update(); - } - - private GetFilter(): Overpass { + private GetFilter(interpreterUrl: string, layersToDownload: LayerConfig[]): Overpass { let filters: TagsFilter[] = []; let extraScripts: string[] = []; - for (const layer of this.state.layoutToUse.data.layers) { - if (typeof (layer) === "string") { - throw "A layer was not expanded!" - } - if (this.state.locationControl.data.zoom < layer.minzoom) { - continue; - } - if (layer.doNotDownload) { - continue; - } - if (layer.source.geojsonSource !== undefined) { - // Not our responsibility to download this layer! - continue; - } - - - // Check if data for this layer has already been loaded - let previouslyLoaded = false; - for (let z = layer.minzoom; z < 25 && !previouslyLoaded; z++) { - const previousLoadedBounds = this._previousBounds.get(z); - if (previousLoadedBounds === undefined) { - continue; - } - for (const previousLoadedBound of previousLoadedBounds) { - previouslyLoaded = previouslyLoaded || this.IsInBounds(previousLoadedBound); - if (previouslyLoaded) { - break; - } - } - } - if (previouslyLoaded) { - continue; - } + for (const layer of layersToDownload) { if (layer.source.overpassScript !== undefined) { extraScripts.push(layer.source.overpassScript) } else { @@ -150,98 +81,113 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour if (filters.length + extraScripts.length === 0) { return undefined; } - return new Overpass(new Or(filters), extraScripts, this.state.overpassUrl, this.state.overpassTimeout, this.relationsTracker); + return new Overpass(new Or(filters), extraScripts, interpreterUrl, this.state.overpassTimeout, this.relationsTracker); } - private update(): void { + private update() { + if (!this._isActive.data) { + return; + } + const self = this; + this.updateAsync().then(bboxDate => { + if(bboxDate === undefined || self.onBboxLoaded === undefined){ + return; + } + const [bbox, date, layers] = bboxDate + self.onBboxLoaded(bbox, date, layers) + }) + } + + private async updateAsync(): Promise<[BBox, Date, LayerConfig[]]> { if (this.runningQuery.data) { console.log("Still running a query, not updating"); - return; + return undefined; } if (this.timeout.data > 0) { console.log("Still in timeout - not updating") - return; + return undefined; } - const bounds = this.state.leafletMap.data?.getBounds()?.pad(this.state.layoutToUse.data.widenFactor); + const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.widenFactor)?.expandToTileBounds(14); + if (bounds === undefined) { - return; + return undefined; } - - const n = Math.min(90, bounds.getNorth()); - const e = Math.min(180, bounds.getEast()); - const s = Math.max(-90, bounds.getSouth()); - const w = Math.max(-180, bounds.getWest()); - const queryBounds = {north: n, east: e, south: s, west: w}; - - const z = Math.floor(this.state.locationControl.data.zoom ?? 0); - const self = this; - const overpass = this.GetFilter(); - if (overpass === undefined) { - return; + + const layersToDownload = [] + for (const layer of this.state.layoutToUse.layers) { + + if (typeof (layer) === "string") { + throw "A layer was not expanded!" + } + if(this.state.locationControl.data.zoom < layer.minzoom){ + continue; + } + if (layer.doNotDownload) { + continue; + } + if (layer.source.geojsonSource !== undefined) { + // Not our responsibility to download this layer! + continue; + } + layersToDownload.push(layer) } - this.runningQuery.setData(true); - overpass.queryGeoJson(queryBounds). - then(([data, date]) => { - self._previousBounds.get(z).push(queryBounds); - self.retries.setData(0); - const features = data.features.map(f => ({feature: f, freshness: date})); - SimpleMetaTagger.objectMetaInfo.addMetaTags(features) - try{ - self.features.setData(features); - }catch(e){ - console.error("Got the overpass response, but could not process it: ", e, e.stack) + let data: any = undefined + let date: Date = undefined + const overpassUrls = self.state.overpassUrl.data + let lastUsed = 0; + + do { + try { + + const overpass = this.GetFilter(overpassUrls[lastUsed], layersToDownload); + + if (overpass === undefined) { + return undefined; } - self.runningQuery.setData(false); - }) - .catch((reason) => { + this.runningQuery.setData(true); + + [data, date] = await overpass.queryGeoJson(bounds) + console.log("Querying overpass is done", data) + } catch (e) { self.retries.data++; - self.ForceRefresh(); - self.timeout.setData(self.retries.data * 5); - console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, reason); self.retries.ping(); - self.runningQuery.setData(false); + console.error(`QUERY FAILED due to`, e); - function countDown() { - window?.setTimeout( - function () { - if (self.timeout.data > 1) { - self.timeout.setData(self.timeout.data - 1); - window.setTimeout( - countDown, - 1000 - ) - } else { - self.timeout.setData(0); - self.update() - } - }, 1000 - ) + await Utils.waitFor(1000) + + if (lastUsed + 1 < overpassUrls.length) { + lastUsed++ + console.log("Trying next time with", overpassUrls[lastUsed]) + } else { + lastUsed = 0 + self.timeout.setData(self.retries.data * 5); + + while (self.timeout.data > 0) { + await Utils.waitFor(1000) + console.log(self.timeout.data) + self.timeout.data-- + self.timeout.ping(); + } } - - countDown(); - } - ); + } while (data === undefined); - - } - - private IsInBounds(bounds: Bounds): boolean { - if (this._previousBounds === undefined) { - return false; + self.retries.setData(0); + try { + data.features.forEach(feature => SimpleMetaTagger.objectMetaInfo.applyMetaTagsOnFeature(feature, date)); + self.features.setData(data.features.map(f => ({feature: f, freshness: date}))); + return [bounds, date, layersToDownload]; + } catch (e) { + console.error("Got the overpass response, but could not process it: ", e, e.stack) + } finally { + self.runningQuery.setData(false); } - const b = this.state.leafletMap.data.getBounds(); - return b.getSouth() >= bounds.south && - b.getNorth() <= bounds.north && - b.getEast() <= bounds.east && - b.getWest() >= bounds.west; + } - - } \ No newline at end of file diff --git a/Logic/Actors/TitleHandler.ts b/Logic/Actors/TitleHandler.ts index 49661f289..91ec89b0c 100644 --- a/Logic/Actors/TitleHandler.ts +++ b/Logic/Actors/TitleHandler.ts @@ -3,12 +3,18 @@ import Translations from "../../UI/i18n/Translations"; import Locale from "../../UI/i18n/Locale"; import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer"; import Combine from "../../UI/Base/Combine"; +import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {ElementStorage} from "../ElementStorage"; export default class TitleHandler { - constructor(state) { + constructor(state : { + selectedElement: UIEventSource, + layoutToUse: LayoutConfig, + allElements: ElementStorage + }) { const currentTitle: UIEventSource = state.selectedElement.map( selected => { - const layout = state.layoutToUse.data + const layout = state.layoutToUse const defaultTitle = Translations.WT(layout?.title)?.txt ?? "MapComplete" if (selected === undefined) { @@ -23,11 +29,11 @@ export default class TitleHandler { if (layer.source.osmTags.matchesProperties(tags)) { const tagsSource = state.allElements.getEventSourceById(tags.id) const title = new TagRenderingAnswer(tagsSource, layer.title) - return new Combine([defaultTitle, " | ", title]).ConstructElement().innerText; + return new Combine([defaultTitle, " | ", title]).ConstructElement()?.innerText ?? defaultTitle; } } return defaultTitle - }, [Locale.language, state.layoutToUse] + }, [Locale.language] ) diff --git a/Logic/BBox.ts b/Logic/BBox.ts new file mode 100644 index 000000000..e642c6ce3 --- /dev/null +++ b/Logic/BBox.ts @@ -0,0 +1,158 @@ +import * as turf from "@turf/turf"; +import {TileRange, Tiles} from "../Models/TileRange"; + +export class BBox { + + readonly maxLat: number; + readonly maxLon: number; + readonly minLat: number; + readonly minLon: number; + static global: BBox = new BBox([[-180, -90], [180, 90]]); + + constructor(coordinates) { + this.maxLat = -90; + this.maxLon = -180; + this.minLat = 90; + this.minLon = 180; + + + for (const coordinate of coordinates) { + this.maxLon = Math.max(this.maxLon, coordinate[0]); + this.maxLat = Math.max(this.maxLat, coordinate[1]); + this.minLon = Math.min(this.minLon, coordinate[0]); + this.minLat = Math.min(this.minLat, coordinate[1]); + } + this.check(); + } + + static fromLeafletBounds(bounds) { + return new BBox([[bounds.getWest(), bounds.getNorth()], [bounds.getEast(), bounds.getSouth()]]) + } + + static get(feature): BBox { + if (feature.bbox?.overlapsWith === undefined) { + const turfBbox: number[] = turf.bbox(feature) + feature.bbox = new BBox([[turfBbox[0], turfBbox[1]], [turfBbox[2], turfBbox[3]]]); + } + return feature.bbox; + } + + /** + * Constructs a tilerange which fully contains this bbox (thus might be a bit larger) + * @param zoomlevel + */ + public containingTileRange(zoomlevel): TileRange{ + return Tiles.TileRangeBetween(zoomlevel, this.minLat, this.minLon, this.maxLat, this.maxLon) + } + + public overlapsWith(other: BBox) { + if (this.maxLon < other.minLon) { + return false; + } + if (this.maxLat < other.minLat) { + return false; + } + if (this.minLon > other.maxLon) { + return false; + } + return this.minLat <= other.maxLat; + + } + + public isContainedIn(other: BBox) { + if (this.maxLon > other.maxLon) { + return false; + } + if (this.maxLat > other.maxLat) { + return false; + } + if (this.minLon < other.minLon) { + return false; + } + if (this.minLat < other.minLat) { + return false + } + return true; + } + + private check() { + if (isNaN(this.maxLon) || isNaN(this.maxLat) || isNaN(this.minLon) || isNaN(this.minLat)) { + console.log(this); + throw "BBOX has NAN"; + } + } + + static fromTile(z: number, x: number, y: number): BBox { + return new BBox(Tiles.tile_bounds_lon_lat(z, x, y)) + } + + static fromTileIndex(i: number): BBox { + if (i === 0) { + return BBox.global + } + return BBox.fromTile(...Tiles.tile_from_index(i)) + } + + getEast() { + return this.maxLon + } + + getNorth() { + return this.maxLat + } + + getWest() { + return this.minLon + } + + getSouth() { + return this.minLat + } + + pad(factor: number): BBox { + const latDiff = this.maxLat - this.minLat + const lat = (this.maxLat + this.minLat) / 2 + const lonDiff = this.maxLon - this.minLon + const lon = (this.maxLon + this.minLon) / 2 + return new BBox([[ + lon - lonDiff * factor, + lat - latDiff * factor + ], [lon + lonDiff * factor, + lat + latDiff * factor]]) + } + + toLeaflet() { + return [[this.minLat, this.minLon], [this.maxLat, this.maxLon]] + } + + asGeoJson(properties: any): any { + return { + type: "Feature", + properties: properties, + geometry: { + type: "Polygon", + coordinates: [[ + + [this.minLon, this.minLat], + [this.maxLon, this.minLat], + [this.maxLon, this.maxLat], + [this.minLon, this.maxLat], + [this.minLon, this.minLat], + + ]] + } + } + } + + /** + * Expands the BBOx so that it contains complete tiles for the given zoomlevel + * @param zoomlevel + */ + expandToTileBounds(zoomlevel: number) : BBox{ + const ul = Tiles.embedded_tile(this.minLat, this.minLon, zoomlevel) + const lr = Tiles.embedded_tile(this.maxLat, this.maxLon, zoomlevel) + const boundsul = Tiles.tile_bounds_lon_lat(ul.z, ul.x, ul.y) + const boundslr = Tiles.tile_bounds_lon_lat(lr.z, lr.x, lr.y) + return new BBox([].concat(boundsul, boundslr)) + } +} \ No newline at end of file diff --git a/Logic/ContributorCount.ts b/Logic/ContributorCount.ts index 2dcd8450f..f39d1106f 100644 --- a/Logic/ContributorCount.ts +++ b/Logic/ContributorCount.ts @@ -2,7 +2,7 @@ import {UIEventSource} from "./UIEventSource"; import FeaturePipeline from "./FeatureSource/FeaturePipeline"; import Loc from "../Models/Loc"; -import {BBox} from "./GeoOperations"; +import {BBox} from "./BBox"; export default class ContributorCount { diff --git a/Logic/ElementStorage.ts b/Logic/ElementStorage.ts index 91193ea6d..ae51094ae 100644 --- a/Logic/ElementStorage.ts +++ b/Logic/ElementStorage.ts @@ -39,11 +39,10 @@ export class ElementStorage { } getEventSourceById(elementId): UIEventSource { - if (this._elements.has(elementId)) { - return this._elements.get(elementId); + if(elementId === undefined){ + return undefined; } - console.error("Can not find eventsource with id ", elementId); - return undefined; + return this._elements.get(elementId); } has(id) { diff --git a/Logic/ExtraFunction.ts b/Logic/ExtraFunction.ts index 8b6834e09..76c28c5a9 100644 --- a/Logic/ExtraFunction.ts +++ b/Logic/ExtraFunction.ts @@ -1,4 +1,4 @@ -import {BBox, GeoOperations} from "./GeoOperations"; +import {GeoOperations} from "./GeoOperations"; import Combine from "../UI/Base/Combine"; import RelationsTracker from "./Osm/RelationsTracker"; import State from "../State"; @@ -7,6 +7,7 @@ import List from "../UI/Base/List"; import Title from "../UI/Base/Title"; import {UIEventSourceTools} from "./UIEventSource"; import AspectedRouting from "./Osm/aspectedRouting"; +import {BBox} from "./BBox"; export interface ExtraFuncParams { /** @@ -134,11 +135,18 @@ export class ExtraFunction { args: ["list of features or layer name", "amount of features", "unique tag key (optional)", "maxDistanceInMeters (optional)"] }, (params, feature) => { - return (features, amount, uniqueTag, maxDistanceInMeters) => ExtraFunction.GetClosestNFeatures(params, feature, features, { - maxFeatures: Number(amount), - uniqueTag: uniqueTag, - maxDistance: Number(maxDistanceInMeters) - }) + + return (features, amount, uniqueTag, maxDistanceInMeters) => { + let distance : number = Number(maxDistanceInMeters) + if(isNaN(distance)){ + distance = undefined + } + return ExtraFunction.GetClosestNFeatures(params, feature, features, { + maxFeatures: Number(amount), + uniqueTag: uniqueTag, + maxDistance: distance + }); + } } ) @@ -249,7 +257,7 @@ export class ExtraFunction { let closestFeatures: { feat: any, distance: number }[] = []; for(const featureList of features) { for (const otherFeature of featureList) { - if (otherFeature == feature || otherFeature.id == feature.id) { + if (otherFeature === feature || otherFeature.id === feature.id) { continue; // We ignore self } let distance = undefined; @@ -261,7 +269,8 @@ export class ExtraFunction { [feature._lon, feature._lat] ) } - if (distance === undefined) { + if (distance === undefined || distance === null) { + console.error("Could not calculate the distance between", feature, "and", otherFeature) throw "Undefined distance!" } if (distance > maxDistance) { diff --git a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts index 331168bb8..2894d56b8 100644 --- a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts +++ b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts @@ -7,26 +7,30 @@ import {FeatureSourceForLayer} from "../FeatureSource"; export default class SaveTileToLocalStorageActor { public static readonly storageKey: string = "cached-features"; + public static readonly formatVersion: string = "1" constructor(source: FeatureSourceForLayer, tileIndex: number) { source.features.addCallbackAndRunD(features => { const key = `${SaveTileToLocalStorageActor.storageKey}-${source.layer.layerDef.id}-${tileIndex}` - const now = new Date().getTime() - - if (features.length == 0) { - return; - } + const now = new Date() try { - localStorage.setItem(key, JSON.stringify(features)); - localStorage.setItem(key + "-time", JSON.stringify(now)) + if (features.length > 0) { + localStorage.setItem(key, JSON.stringify(features)); + } + // We _still_ write the time to know that this tile is empty! + SaveTileToLocalStorageActor.MarkVisited(source.layer.layerDef.id, tileIndex, now) } catch (e) { console.warn("Could not save the features to local storage:", e) } }) - - } + public static MarkVisited(layerId: string, tileId: number, freshness: Date){ + const key = `${SaveTileToLocalStorageActor.storageKey}-${layerId}-${tileId}` + localStorage.setItem(key + "-time", JSON.stringify(freshness.getTime())) + localStorage.setItem(key + "-format", SaveTileToLocalStorageActor.formatVersion) + + } } \ No newline at end of file diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index c6206eac4..5d5b3e166 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -1,7 +1,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import FilteringFeatureSource from "./Sources/FilteringFeatureSource"; import PerLayerFeatureSourceSplitter from "./PerLayerFeatureSourceSplitter"; -import FeatureSource, {FeatureSourceForLayer, FeatureSourceState, IndexedFeatureSource, Tiled} from "./FeatureSource"; +import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "./FeatureSource"; import TiledFeatureSource from "./TiledFeatureSource/TiledFeatureSource"; import {UIEventSource} from "../UIEventSource"; import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy"; @@ -17,76 +17,111 @@ import RegisteringAllFromFeatureSourceActor from "./Actors/RegisteringAllFromFea import TiledFromLocalStorageSource from "./TiledFeatureSource/TiledFromLocalStorageSource"; import SaveTileToLocalStorageActor from "./Actors/SaveTileToLocalStorageActor"; import DynamicGeoJsonTileSource from "./TiledFeatureSource/DynamicGeoJsonTileSource"; -import {BBox} from "../GeoOperations"; import {TileHierarchyMerger} from "./TiledFeatureSource/TileHierarchyMerger"; import RelationsTracker from "../Osm/RelationsTracker"; import {NewGeometryFromChangesFeatureSource} from "./Sources/NewGeometryFromChangesFeatureSource"; import ChangeGeometryApplicator from "./Sources/ChangeGeometryApplicator"; +import {BBox} from "../BBox"; +import OsmFeatureSource from "./TiledFeatureSource/OsmFeatureSource"; +import {OsmConnection} from "../Osm/OsmConnection"; +import {Tiles} from "../../Models/TileRange"; +import TileFreshnessCalculator from "./TileFreshnessCalculator"; -export default class FeaturePipeline implements FeatureSourceState { +export default class FeaturePipeline { public readonly sufficientlyZoomed: UIEventSource; + public readonly runningQuery: UIEventSource; public readonly timeout: UIEventSource; + public readonly somethingLoaded: UIEventSource = new UIEventSource(false) public readonly newDataLoadedSignal: UIEventSource = new UIEventSource(undefined) private readonly overpassUpdater: OverpassFeatureSource + private state: { + readonly filteredLayers: UIEventSource, + readonly locationControl: UIEventSource, + readonly selectedElement: UIEventSource, + readonly changes: Changes, + readonly layoutToUse: LayoutConfig, + readonly leafletMap: any, + readonly overpassUrl: UIEventSource; + readonly overpassTimeout: UIEventSource; + readonly overpassMaxZoom: UIEventSource; + readonly osmConnection: OsmConnection + readonly currentBounds: UIEventSource + }; private readonly relationTracker: RelationsTracker private readonly perLayerHierarchy: Map; + private readonly freshnesses = new Map(); + + private readonly oldestAllowedDate: Date = new Date(new Date().getTime() - 60 * 60 * 24 * 30 * 1000); + private readonly osmSourceZoomLevel = 14 + constructor( - handleFeatureSource: (source: FeatureSourceForLayer) => void, + handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void, state: { - filteredLayers: UIEventSource, - locationControl: UIEventSource, - selectedElement: UIEventSource, - changes: Changes, - layoutToUse: UIEventSource, - leafletMap: any, - readonly overpassUrl: UIEventSource; + readonly filteredLayers: UIEventSource, + readonly locationControl: UIEventSource, + readonly selectedElement: UIEventSource, + readonly changes: Changes, + readonly layoutToUse: LayoutConfig, + readonly leafletMap: any, + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource; + readonly osmConnection: OsmConnection + readonly currentBounds: UIEventSource }) { + this.state = state; const self = this - const updater = new OverpassFeatureSource(state); - updater.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(updater)) - this.overpassUpdater = updater; - this.sufficientlyZoomed = updater.sufficientlyZoomed - this.runningQuery = updater.runningQuery - this.timeout = updater.timeout - this.relationTracker = updater.relationsTracker - // Register everything in the state' 'AllElements' - new RegisteringAllFromFeatureSourceActor(updater) - + // milliseconds + const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12)) + this.relationTracker = new RelationsTracker() + + const neededTilesFromOsm = this.getNeededTilesFromOsm() + + + this.sufficientlyZoomed = state.locationControl.map(location => { + if (location?.zoom === undefined) { + return false; + } + let minzoom = Math.min(...state.layoutToUse.layers.map(layer => layer.minzoom ?? 18)); + return location.zoom >= minzoom; + } + ); + const perLayerHierarchy = new Map() this.perLayerHierarchy = perLayerHierarchy - const patchedHandleFeatureSource = function (src: FeatureSourceForLayer & IndexedFeatureSource) { + const patchedHandleFeatureSource = function (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled) { // This will already contain the merged features for this tile. In other words, this will only be triggered once for every tile const srcFiltered = - new FilteringFeatureSource(state, + new FilteringFeatureSource(state, src.tileIndex, new WayHandlingApplyingFeatureSource( new ChangeGeometryApplicator(src, state.changes) ) ) + handleFeatureSource(srcFiltered) self.somethingLoaded.setData(true) + self.freshnesses.get(src.layer.layerDef.id).addTileLoad(src.tileIndex, new Date()) }; - function addToHierarchy(src: FeatureSource & Tiled, layerId: string) { - perLayerHierarchy.get(layerId).registerTile(src) - } for (const filteredLayer of state.filteredLayers.data) { - const hierarchy = new TileHierarchyMerger(filteredLayer, (tile, _) => patchedHandleFeatureSource(tile)) const id = filteredLayer.layerDef.id - perLayerHierarchy.set(id, hierarchy) const source = filteredLayer.layerDef.source + const hierarchy = new TileHierarchyMerger(filteredLayer, (tile, _) => patchedHandleFeatureSource(tile)) + perLayerHierarchy.set(id, hierarchy) + + this.freshnesses.set(id, new TileFreshnessCalculator()) + if (source.geojsonSource === undefined) { // This is an OSM layer // We load the cached values and register them @@ -97,49 +132,81 @@ export default class FeaturePipeline implements FeatureSourceState { hierarchy.registerTile(src); src.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(src)) }, state) + + TiledFromLocalStorageSource.GetFreshnesses(id).forEach((value, key) => { + self.freshnesses.get(id).addTileLoad(key, value) + }) + continue } if (source.geojsonZoomLevel === undefined) { // This is a 'load everything at once' geojson layer - // We split them up into tiles + // We split them up into tiles anyway const src = new GeoJsonSource(filteredLayer) TiledFeatureSource.createHierarchy(src, { layer: src.layer, + minZoomLevel: 14, + dontEnforceMinZoom: true, registerTile: (tile) => { new RegisteringAllFromFeatureSourceActor(tile) - addToHierarchy(tile, id) + perLayerHierarchy.get(id).registerTile(tile) tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) } }) } else { new DynamicGeoJsonTileSource( filteredLayer, - src => TiledFeatureSource.createHierarchy(src, { - layer: src.layer, - registerTile: (tile) => { - new RegisteringAllFromFeatureSourceActor(tile) - addToHierarchy(tile, id) - tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) - } - }), + tile => { + new RegisteringAllFromFeatureSourceActor(tile) + perLayerHierarchy.get(id).registerTile(tile) + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + }, state ) } - } + + const osmFeatureSource = new OsmFeatureSource({ + isActive: useOsmApi, + neededTiles: neededTilesFromOsm, + handleTile: tile => { + new RegisteringAllFromFeatureSourceActor(tile) + new SaveTileToLocalStorageActor(tile, tile.tileIndex) + perLayerHierarchy.get(tile.layer.layerDef.id).registerTile(tile) + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + + }, + state: state, + markTileVisited: (tileId) => + state.filteredLayers.data.forEach(flayer => { + SaveTileToLocalStorageActor.MarkVisited(flayer.layerDef.id, tileId, new Date()) + }) + }) + + + const updater = this.initOverpassUpdater(state, useOsmApi) + this.overpassUpdater = updater; + this.timeout = updater.timeout + // Actually load data from the overpass source new PerLayerFeatureSourceSplitter(state.filteredLayers, (source) => TiledFeatureSource.createHierarchy(source, { layer: source.layer, + minZoomLevel: 14, + dontEnforceMinZoom: true, + maxFeatureCount: state.layoutToUse.clustering.minNeededElements, + maxZoomLevel: state.layoutToUse.clustering.maxZoom, registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) - addToHierarchy(tile, source.layer.layerDef.id); + perLayerHierarchy.get(source.layer.layerDef.id).registerTile(new RememberingSource(tile)) + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + } }), - new RememberingSource(updater)) + updater) // Also load points/lines that are newly added. @@ -149,9 +216,11 @@ export default class FeaturePipeline implements FeatureSourceState { new PerLayerFeatureSourceSplitter(state.filteredLayers, (perLayer) => { // We don't bother to split them over tiles as it'll contain little features by default, so we simply add them like this - addToHierarchy(perLayer, perLayer.layer.layerDef.id) + perLayerHierarchy.get(perLayer.layer.layerDef.id).registerTile(perLayer) // AT last, we always apply the metatags whenever possible perLayer.features.addCallbackAndRunD(_ => self.applyMetaTags(perLayer)) + perLayer.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(perLayer)) + }, newGeometry ) @@ -162,27 +231,141 @@ export default class FeaturePipeline implements FeatureSourceState { self.updateAllMetaTagging() }) - } - - private applyMetaTags(src: FeatureSourceForLayer){ - const self = this - MetaTagging.addMetatags( - src.features.data, - { - memberships: this.relationTracker, - getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox) - }, - src.layer.layerDef, - { - includeDates: true, - // We assume that the non-dated metatags are already set by the cache generator - includeNonDates: !src.layer.layerDef.source.isOsmCacheLayer - } + + this.runningQuery = updater.runningQuery.map( + overpass => overpass || osmFeatureSource.isRunning.data, [osmFeatureSource.isRunning] ) + + + } + + private freshnessForVisibleLayers(z: number, x: number, y: number): Date { + let oldestDate = undefined; + for (const flayer of this.state.filteredLayers.data) { + if (!flayer.isDisplayed.data) { + continue + } + if (this.state.locationControl.data.zoom < flayer.layerDef.minzoom) { + continue; + } + const freshness = this.freshnesses.get(flayer.layerDef.id).freshnessFor(z, x, y) + if (freshness === undefined) { + // SOmething is undefined --> we return undefined as we have to download + return undefined + } + if (oldestDate === undefined || oldestDate > freshness) { + oldestDate = freshness + } + } + return oldestDate + } + + private getNeededTilesFromOsm(): UIEventSource { + const self = this + return this.state.currentBounds.map(bbox => { + if (bbox === undefined) { + return + } + const osmSourceZoomLevel = self.osmSourceZoomLevel + const range = bbox.containingTileRange(osmSourceZoomLevel) + const tileIndexes = [] + if (range.total > 100) { + // Too much tiles! + return [] + } + Tiles.MapRange(range, (x, y) => { + const i = Tiles.tile_index(osmSourceZoomLevel, x, y); + const oldestDate = self.freshnessForVisibleLayers(osmSourceZoomLevel, x, y) + if (oldestDate !== undefined && oldestDate > this.oldestAllowedDate) { + console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") + // The cached tiles contain decently fresh data + return; + } + tileIndexes.push(i) + }) + return tileIndexes + }) + } + + private initOverpassUpdater(state: { + layoutToUse: LayoutConfig, + currentBounds: UIEventSource, + locationControl: UIEventSource, + readonly overpassUrl: UIEventSource; + readonly overpassTimeout: UIEventSource; + readonly overpassMaxZoom: UIEventSource, + }, useOsmApi: UIEventSource): OverpassFeatureSource { + const minzoom = Math.min(...state.layoutToUse.layers.map(layer => layer.minzoom)) + const allUpToDateAndZoomSufficient = state.currentBounds.map(bbox => { + if (bbox === undefined) { + return true + } + let zoom = state.locationControl.data.zoom + if (zoom < minzoom) { + return true; + } + if (zoom > 16) { + zoom = 16 + } + if (zoom < 8) { + zoom = zoom + 2 + } + const range = bbox.containingTileRange(zoom) + const self = this; + const allFreshnesses = Tiles.MapRange(range, (x, y) => self.freshnessForVisibleLayers(zoom, x, y)) + return !allFreshnesses.some(freshness => freshness === undefined || freshness < this.oldestAllowedDate) + + }, [state.locationControl]) + + allUpToDateAndZoomSufficient.addCallbackAndRunD(allUpToDate => console.log("All up to data is: ", allUpToDate)) + const self = this; + const updater = new OverpassFeatureSource(state, + { + relationTracker: this.relationTracker, + isActive: useOsmApi.map(b => !b && !allUpToDateAndZoomSufficient.data, [allUpToDateAndZoomSufficient]), + onBboxLoaded: ((bbox, date, downloadedLayers) => { + Tiles.MapRange(bbox.containingTileRange(self.osmSourceZoomLevel), (x, y) => { + downloadedLayers.forEach(layer => { + SaveTileToLocalStorageActor.MarkVisited(layer.id, Tiles.tile_index(this.osmSourceZoomLevel, x, y), date) + }) + }) + + }) + }); + + + // Register everything in the state' 'AllElements' + new RegisteringAllFromFeatureSourceActor(updater) + return updater; + } + + private applyMetaTags(src: FeatureSourceForLayer) { + const self = this + console.debug("Applying metatagging onto ", src.name) + window.setTimeout( + () => { + MetaTagging.addMetatags( + src.features.data, + { + memberships: this.relationTracker, + getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox) + }, + src.layer.layerDef, + { + includeDates: true, + // We assume that the non-dated metatags are already set by the cache generator + includeNonDates: !src.layer.layerDef.source.isOsmCacheLayer + } + ) + }, + 15 + ) + } private updateAllMetaTagging() { const self = this; + console.log("Reupdating all metatagging") this.perLayerHierarchy.forEach(hierarchy => { hierarchy.loadedTiles.forEach(src => { self.applyMetaTags(src) @@ -216,7 +399,4 @@ export default class FeaturePipeline implements FeatureSourceState { }) } - public ForceRefresh() { - this.overpassUpdater.ForceRefresh() - } } \ No newline at end of file diff --git a/Logic/FeatureSource/FeatureSource.ts b/Logic/FeatureSource/FeatureSource.ts index 791882e11..7d603d1f6 100644 --- a/Logic/FeatureSource/FeatureSource.ts +++ b/Logic/FeatureSource/FeatureSource.ts @@ -1,7 +1,7 @@ import {UIEventSource} from "../UIEventSource"; import {Utils} from "../../Utils"; import FilteredLayer from "../../Models/FilteredLayer"; -import {BBox} from "../GeoOperations"; +import {BBox} from "../BBox"; export default interface FeatureSource { features: UIEventSource<{ feature: any, freshness: Date }[]>; diff --git a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts index d16e2c558..f9a0cbe1a 100644 --- a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts +++ b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts @@ -15,6 +15,7 @@ export default class PerLayerFeatureSourceSplitter { handleLayerData: (source: FeatureSourceForLayer & Tiled) => void, upstream: FeatureSource, options?:{ + tileIndex?: number, handleLeftovers?: (featuresWithoutLayer: any[]) => void }) { @@ -71,7 +72,7 @@ export default class PerLayerFeatureSourceSplitter { let featureSource = knownLayers.get(id) if (featureSource === undefined) { // Not yet initialized - now is a good time - featureSource = new SimpleFeatureSource(layer) + featureSource = new SimpleFeatureSource(layer, options?.tileIndex) featureSource.features.setData(features) knownLayers.set(id, featureSource) handleLayerData(featureSource) diff --git a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts index fb349ae5d..b1797d0ae 100644 --- a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts +++ b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts @@ -5,8 +5,9 @@ import {UIEventSource} from "../../UIEventSource"; import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class FeatureSourceMerger implements FeatureSourceForLayer, Tiled, IndexedFeatureSource { @@ -23,7 +24,7 @@ export default class FeatureSourceMerger implements FeatureSourceForLayer, Tiled this.bbox = bbox; this._sources = sources; this.layer = layer; - this.name = "FeatureSourceMerger("+layer.layerDef.id+", "+Utils.tile_from_index(tileIndex).join(",")+")" + this.name = "FeatureSourceMerger("+layer.layerDef.id+", "+Tiles.tile_from_index(tileIndex).join(",")+")" const self = this; const handledSources = new Set(); diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 6848f9f26..0c2c9d92a 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -1,29 +1,36 @@ import {UIEventSource} from "../../UIEventSource"; import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {FeatureSourceForLayer} from "../FeatureSource"; +import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import Hash from "../../Web/Hash"; +import {BBox} from "../../BBox"; -export default class FilteringFeatureSource implements FeatureSourceForLayer { +export default class FilteringFeatureSource implements FeatureSourceForLayer, Tiled { public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name; public readonly layer: FilteredLayer; + public readonly tileIndex: number + public readonly bbox: BBox constructor( state: { locationControl: UIEventSource<{ zoom: number }>, selectedElement: UIEventSource, }, + tileIndex, upstream: FeatureSourceForLayer ) { const self = this; - this.name = "FilteringFeatureSource("+upstream.name+")" + this.name = "FilteringFeatureSource(" + upstream.name + ")" + this.tileIndex = tileIndex + this.bbox = BBox.fromTileIndex(tileIndex) this.layer = upstream.layer; const layer = upstream.layer; - + function update() { + const features: { feature: any; freshness: Date }[] = upstream.features.data; const newFeatures = features.filter((f) => { if ( @@ -45,17 +52,15 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { } const tagsFilter = layer.appliedFilters.data; - if (tagsFilter) { - if (!tagsFilter.matchesProperties(f.feature.properties)) { + for (const filter of tagsFilter ?? []) { + const neededTags = filter.filter.options[filter.selected].osmTags + if (!neededTags.matchesProperties(f.feature.properties)) { // Hidden by the filter on the layer itself - we want to hide it no matter wat return false; } } - if (!FilteringFeatureSource.showLayer(layer, state.locationControl.data)) { - // The layer itself is either disabled or hidden due to zoom constraints - // We should return true, but it might still match some other layer - return false; - } + + return true; }); @@ -66,23 +71,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { update(); }); - let isShown = state.locationControl.map((l) => FilteringFeatureSource.showLayer(layer, l), - [layer.isDisplayed]) - - isShown.addCallback(isShown => { - if (isShown) { - update(); - } else { - self.features.setData([]) - } - }); layer.appliedFilters.addCallback(_ => { - if(!isShown.data){ - // Currently not shown. - // Note that a change in 'isSHown' will trigger an update as well, so we don't have to watch it another time - return; - } update() }) @@ -93,10 +83,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { layer: { isDisplayed: UIEventSource; layerDef: LayerConfig; - }, - location: { zoom: number }) { - return layer.isDisplayed.data && - layer.layerDef.minzoomVisible <= location.zoom; + }) { + return layer.isDisplayed.data; } } diff --git a/Logic/FeatureSource/Sources/GeoJsonSource.ts b/Logic/FeatureSource/Sources/GeoJsonSource.ts index e6d24fbca..b341a0dd3 100644 --- a/Logic/FeatureSource/Sources/GeoJsonSource.ts +++ b/Logic/FeatureSource/Sources/GeoJsonSource.ts @@ -5,7 +5,8 @@ import {UIEventSource} from "../../UIEventSource"; import FilteredLayer from "../../../Models/FilteredLayer"; import {Utils} from "../../../Utils"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { @@ -20,14 +21,26 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { public readonly tileIndex public readonly bbox; + /** + * Only used if the actual source is a tiled geojson. + * A big feature might be contained in multiple tiles. + * However, we only want to load them once. The blacklist thus contains all ids of all features previously seen + * @private + */ + private readonly featureIdBlacklist?: UIEventSource> + public constructor(flayer: FilteredLayer, - zxy?: [number, number, number]) { + zxy?: [number, number, number], + options?: { + featureIdBlacklist?: UIEventSource> + }) { if (flayer.layerDef.source.geojsonZoomLevel !== undefined && zxy === undefined) { throw "Dynamic layers are not supported. Use 'DynamicGeoJsonTileSource instead" } this.layer = flayer; + this.featureIdBlacklist = options?.featureIdBlacklist let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id); if (zxy !== undefined) { const [z, x, y] = zxy; @@ -35,10 +48,10 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { .replace('{z}', "" + z) .replace('{x}', "" + x) .replace('{y}', "" + y) - this.tileIndex = Utils.tile_index(z, x, y) + this.tileIndex = Tiles.tile_index(z, x, y) this.bbox = BBox.fromTile(z, x, y) } else { - this.tileIndex = Utils.tile_index(0, 0, 0) + this.tileIndex = Tiles.tile_index(0, 0, 0) this.bbox = BBox.global; } @@ -67,6 +80,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { const props = feature.properties for (const key in props) { if (typeof props[key] !== "string") { + // Make sure all the values are string, it crashes stuff otherwise props[key] = "" + props[key] } } @@ -81,6 +95,10 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { continue; } self.seenids.add(props.id) + + if(self.featureIdBlacklist?.data?.has(props.id)){ + continue; + } let freshness: Date = time; if (feature.properties["_last_edit:timestamp"] !== undefined) { @@ -89,7 +107,6 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { newFeatures.push({feature: feature, freshness: freshness}) } - console.debug("Downloaded " + newFeatures.length + " new features and " + skipped + " already seen features from " + url); if (newFeatures.length == 0) { return; diff --git a/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts b/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts index f4619b2aa..0a1c67f41 100644 --- a/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts +++ b/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts @@ -3,6 +3,7 @@ import {OsmNode, OsmRelation, OsmWay} from "../../Osm/OsmObject"; import FeatureSource from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import {ChangeDescription} from "../../Osm/Actions/ChangeDescription"; +import State from "../../../State"; export class NewGeometryFromChangesFeatureSource implements FeatureSource { // This class name truly puts the 'Java' into 'Javascript' @@ -54,6 +55,9 @@ export class NewGeometryFromChangesFeatureSource implements FeatureSource { tags[kv.k] = kv.v } tags["id"] = change.type+"/"+change.id + + tags["_backend"] = State.state.osmConnection._oauth_config.url + switch (change.type) { case "node": const n = new OsmNode(change.id) diff --git a/Logic/FeatureSource/Sources/RememberingSource.ts b/Logic/FeatureSource/Sources/RememberingSource.ts index 99f422478..683576736 100644 --- a/Logic/FeatureSource/Sources/RememberingSource.ts +++ b/Logic/FeatureSource/Sources/RememberingSource.ts @@ -2,17 +2,23 @@ * Every previously added point is remembered, but new points are added. * Data coming from upstream will always overwrite a previous value */ -import FeatureSource from "../FeatureSource"; +import FeatureSource, {Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; +import {BBox} from "../../BBox"; -export default class RememberingSource implements FeatureSource { +export default class RememberingSource implements FeatureSource , Tiled{ public readonly features: UIEventSource<{ feature: any, freshness: Date }[]>; public readonly name; - - constructor(source: FeatureSource) { + public readonly tileIndex : number + public readonly bbox : BBox + + constructor(source: FeatureSource & Tiled) { const self = this; this.name = "RememberingSource of " + source.name; + this.tileIndex= source.tileIndex + this.bbox = source.bbox; + const empty = []; this.features = source.features.map(features => { const oldFeatures = self.features?.data ?? empty; diff --git a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts index ad8d7be5d..b06aae6d2 100644 --- a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts +++ b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts @@ -1,19 +1,22 @@ import {UIEventSource} from "../../UIEventSource"; import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class SimpleFeatureSource implements FeatureSourceForLayer, Tiled { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name: string = "SimpleFeatureSource"; public readonly layer: FilteredLayer; public readonly bbox: BBox = BBox.global; - public readonly tileIndex: number = Utils.tile_index(0, 0, 0); + public readonly tileIndex: number; - constructor(layer: FilteredLayer) { + constructor(layer: FilteredLayer, tileIndex: number) { this.name = "SimpleFeatureSource(" + layer.layerDef.id + ")" this.layer = layer + this.tileIndex = tileIndex ?? 0; + this.bbox = BBox.fromTileIndex(this.tileIndex) } } \ No newline at end of file diff --git a/Logic/FeatureSource/Sources/StaticFeatureSource.ts b/Logic/FeatureSource/Sources/StaticFeatureSource.ts index 0cc58d656..d5795a1d5 100644 --- a/Logic/FeatureSource/Sources/StaticFeatureSource.ts +++ b/Logic/FeatureSource/Sources/StaticFeatureSource.ts @@ -8,12 +8,13 @@ export default class StaticFeatureSource implements FeatureSource { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; public readonly name: string = "StaticFeatureSource" - constructor(features: any[] | UIEventSource, useFeaturesDirectly = false) { + constructor(features: any[] | UIEventSource>, useFeaturesDirectly) { const now = new Date(); - if(useFeaturesDirectly){ + if (useFeaturesDirectly) { // @ts-ignore this.features = features - }else if (features instanceof UIEventSource) { + } else if (features instanceof UIEventSource) { + // @ts-ignore this.features = features.map(features => features.map(f => ({feature: f, freshness: now}))) } else { this.features = new UIEventSource(features.map(f => ({ diff --git a/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts b/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts index 37ee94b8a..cb36c4b21 100644 --- a/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts +++ b/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts @@ -12,10 +12,11 @@ export default class WayHandlingApplyingFeatureSource implements FeatureSourceFo public readonly layer; constructor(upstream: FeatureSourceForLayer) { - this.name = "Wayhandling(" + upstream.name+")"; + + this.name = "Wayhandling(" + upstream.name + ")"; this.layer = upstream.layer const layer = upstream.layer.layerDef; - + if (layer.wayHandling === LayerConfig.WAYHANDLING_DEFAULT) { // We don't have to do anything fancy // lets just wire up the upstream diff --git a/Logic/FeatureSource/TileFreshnessCalculator.ts b/Logic/FeatureSource/TileFreshnessCalculator.ts new file mode 100644 index 000000000..6b397f540 --- /dev/null +++ b/Logic/FeatureSource/TileFreshnessCalculator.ts @@ -0,0 +1,72 @@ +import {Tiles} from "../../Models/TileRange"; + +export default class TileFreshnessCalculator { + + /** + * All the freshnesses per tile index + * @private + */ + private readonly freshnesses = new Map(); + + /** + * Marks that some data got loaded for this layer + * @param tileId + * @param freshness + */ + public addTileLoad(tileId: number, freshness: Date){ + const existingFreshness = this.freshnessFor(...Tiles.tile_from_index(tileId)) + if(existingFreshness >= freshness){ + return; + } + this.freshnesses.set(tileId, freshness) + + + // Do we have freshness for the neighbouring tiles? If so, we can mark the tile above as loaded too! + let [z, x, y] = Tiles.tile_from_index(tileId) + if(z === 0){ + return; + } + x = x - (x % 2) // Make the tiles always even + y = y - (y % 2) + + const ul = this.freshnessFor(z, x, y)?.getTime() + if(ul === undefined){ + return + } + const ur = this.freshnessFor(z, x + 1, y)?.getTime() + if(ur === undefined){ + return + } + const ll = this.freshnessFor(z, x, y + 1)?.getTime() + if(ll === undefined){ + return + } + const lr = this.freshnessFor(z, x + 1, y + 1)?.getTime() + if(lr === undefined){ + return + } + + const leastFresh = Math.min(ul, ur, ll, lr) + const date = new Date() + date.setTime(leastFresh) + this.addTileLoad( + Tiles.tile_index(z - 1, Math.floor(x / 2), Math.floor(y / 2)), + date + ) + + } + + public freshnessFor(z: number, x: number, y:number): Date { + if(z < 0){ + return undefined + } + const tileId = Tiles.tile_index(z, x, y) + if(this.freshnesses.has(tileId)) { + return this.freshnesses.get(tileId) + } + // recurse up + return this.freshnessFor(z - 1, Math.floor(x /2), Math.floor(y / 2)) + + } + +} \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts index 357db85d4..fcfdbea5a 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts @@ -1,5 +1,5 @@ import FilteredLayer from "../../../Models/FilteredLayer"; -import {FeatureSourceForLayer} from "../FeatureSource"; +import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import DynamicTileSource from "./DynamicTileSource"; @@ -8,7 +8,7 @@ import GeoJsonSource from "../Sources/GeoJsonSource"; export default class DynamicGeoJsonTileSource extends DynamicTileSource { constructor(layer: FilteredLayer, - registerLayer: (layer: FeatureSourceForLayer) => void, + registerLayer: (layer: FeatureSourceForLayer & Tiled) => void, state: { locationControl: UIEventSource leafletMap: any @@ -37,6 +37,8 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource { console.warn("No whitelist found for ", layer.layerDef.id, err) }) + const seenIds = new Set(); + const blackList = new UIEventSource(seenIds) super( layer, source.geojsonZoomLevel, @@ -50,8 +52,15 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource { const src = new GeoJsonSource( layer, - zxy + zxy, + { + featureIdBlacklist: blackList + } ) + src.features.addCallbackAndRunD(feats => { + feats.forEach(feat => seenIds.add(feat.feature.properties.id)) + blackList.ping(); + }) registerLayer(src) return src }, diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts index 43021587c..a6ef04458 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts @@ -6,6 +6,7 @@ import {Utils} from "../../../Utils"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import TileHierarchy from "./TileHierarchy"; +import {Tiles} from "../../../Models/TileRange"; /*** * A tiled source which dynamically loads the required tiles at a fixed zoom level @@ -46,9 +47,9 @@ export default class DynamicTileSource implements TileHierarchy Utils.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i)) + const needed = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i)) if (needed.length === 0) { return undefined } @@ -63,7 +64,7 @@ export default class DynamicTileSource implements TileHierarchy = new UIEventSource(false) + private readonly filteredLayers: UIEventSource; + private readonly handleTile: (fs: (FeatureSourceForLayer & Tiled)) => void; + private isActive: UIEventSource; + private options: { + handleTile: (tile: FeatureSourceForLayer & Tiled) => void; + isActive: UIEventSource, + neededTiles: UIEventSource, + state: { + readonly osmConnection: OsmConnection; + }, + markTileVisited?: (tileId: number) => void + }; + private readonly downloadedTiles = new Set() + + constructor(options: { + handleTile: (tile: FeatureSourceForLayer & Tiled) => void; + isActive: UIEventSource, + neededTiles: UIEventSource, + state: { + readonly filteredLayers: UIEventSource; + readonly osmConnection: OsmConnection; + }, + markTileVisited?: (tileId: number) => void + }) { + this.options = options; + this._backend = options.state.osmConnection._oauth_config.url; + this.filteredLayers = options.state.filteredLayers.map(layers => layers.filter(layer => layer.layerDef.source.geojsonSource === undefined)) + this.handleTile = options.handleTile + this.isActive = options.isActive + const self = this + options.neededTiles.addCallbackAndRunD(neededTiles => { + if (options.isActive?.data === false) { + return; + } + + self.isRunning.setData(true) + try { + + for (const neededTile of neededTiles) { + if (self.downloadedTiles.has(neededTile)) { + return; + } + self.downloadedTiles.add(neededTile) + Promise.resolve(self.LoadTile(...Tiles.tile_from_index(neededTile)).then(_ => { + })) + } + } catch (e) { + console.error(e) + } + self.isRunning.setData(false) + }) + } + + private async LoadTile(z, x, y): Promise { + if (z > 20) { + throw "This is an absurd high zoom level" + } + + const bbox = BBox.fromTile(z, x, y) + const url = `${this._backend}/api/0.6/map?bbox=${bbox.minLon},${bbox.minLat},${bbox.maxLon},${bbox.maxLat}` + try { + + console.log("Attempting to get tile", z, x, y, "from the osm api") + const osmXml = await Utils.download(url, {"accept": "application/xml"}) + try { + const parsed = new DOMParser().parseFromString(osmXml, "text/xml"); + console.log("Got tile", z, x, y, "from the osm api") + const geojson = OsmToGeoJson.default(parsed, + // @ts-ignore + { + flatProperties: true + }); + console.log("Tile geojson:", z, x, y, "is", geojson) + const index = Tiles.tile_index(z, x, y); + new PerLayerFeatureSourceSplitter(this.filteredLayers, + this.handleTile, + new StaticFeatureSource(geojson.features, false), + { + tileIndex:index + } + ); + if(this.options.markTileVisited){ + this.options.markTileVisited(index) + } + } catch (e) { + console.error("Weird error: ", e) + } + } catch (e) { + console.error("Could not download tile", z, x, y, "due to", e, "; retrying with smaller bounds") + if (e === "rate limited") { + return; + } + await this.LoadTile(z + 1, x * 2, y * 2) + await this.LoadTile(z + 1, 1 + x * 2, y * 2) + await this.LoadTile(z + 1, x * 2, 1 + y * 2) + await this.LoadTile(z + 1, 1 + x * 2, 1 + y * 2) + return; + } + + + } + +} \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts b/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts index d905d2f65..f2e43069d 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts @@ -1,5 +1,5 @@ import FeatureSource, {Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; +import {BBox} from "../../BBox"; export default interface TileHierarchy { diff --git a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts index 7b9f44b9c..6fd3dae65 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts @@ -2,9 +2,9 @@ import TileHierarchy from "./TileHierarchy"; import {UIEventSource} from "../../UIEventSource"; import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {Utils} from "../../../Utils"; -import {BBox} from "../../GeoOperations"; import FeatureSourceMerger from "../Sources/FeatureSourceMerger"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export class TileHierarchyMerger implements TileHierarchy { public readonly loadedTiles: Map = new Map(); @@ -13,7 +13,7 @@ export class TileHierarchyMerger implements TileHierarchy void; - constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource, index: number) => void) { + constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled, index: number) => void) { this.layer = layer; this._handleTile = handleTile; } @@ -37,7 +37,7 @@ export class TileHierarchyMerger implements TileHierarchy([src]) this.sources.set(index, sources) - const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Utils.tile_from_index(index)), sources) + const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Tiles.tile_from_index(index)), sources) this.loadedTiles.set(index, merger) this._handleTile(merger, index) } diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts index 62a7c9e5e..4950ea328 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts @@ -1,10 +1,10 @@ import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import {Utils} from "../../../Utils"; -import {BBox} from "../../GeoOperations"; import FilteredLayer from "../../../Models/FilteredLayer"; import TileHierarchy from "./TileHierarchy"; -import {feature} from "@turf/turf"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; /** * Contains all features in a tiled fashion. @@ -41,12 +41,12 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, this.x = x; this.y = y; this.bbox = BBox.fromTile(z, x, y) - this.tileIndex = Utils.tile_index(z, x, y) + this.tileIndex = Tiles.tile_index(z, x, y) this.name = `TiledFeatureSource(${z},${x},${y})` this.parent = parent; this.layer = options.layer options = options ?? {} - this.maxFeatureCount = options?.maxFeatureCount ?? 500; + this.maxFeatureCount = options?.maxFeatureCount ?? 250; this.maxzoom = options.maxZoomLevel ?? 18 this.options = options; if (parent === undefined) { @@ -61,7 +61,7 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, } else { this.root = this.parent.root; this.loadedTiles = this.root.loadedTiles; - const i = Utils.tile_index(z, x, y) + const i = Tiles.tile_index(z, x, y) this.root.loadedTiles.set(i, this) } this.features = new UIEventSource([]) @@ -109,7 +109,6 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, // To much features - we split return featureCount > this.maxFeatureCount - } /*** @@ -143,9 +142,20 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, for (const feature of features) { const bbox = BBox.get(feature.feature) - if (this.options.minZoomLevel === undefined) { - + if (this.options.dontEnforceMinZoom) { + if (bbox.overlapsWith(this.upper_left.bbox)) { + ulf.push(feature) + } else if (bbox.overlapsWith(this.upper_right.bbox)) { + urf.push(feature) + } else if (bbox.overlapsWith(this.lower_left.bbox)) { + llf.push(feature) + } else if (bbox.overlapsWith(this.lower_right.bbox)) { + lrf.push(feature) + } else { + overlapsboundary.push(feature) + } + }else if (this.options.minZoomLevel === undefined) { if (bbox.isContainedIn(this.upper_left.bbox)) { ulf.push(feature) } else if (bbox.isContainedIn(this.upper_right.bbox)) { @@ -186,6 +196,11 @@ export interface TiledFeatureSourceOptions { readonly maxFeatureCount?: number, readonly maxZoomLevel?: number, readonly minZoomLevel?: number, + /** + * IF minZoomLevel is set, and if a feature runs through a tile boundary, it would normally be duplicated. + * Setting 'dontEnforceMinZoomLevel' will still allow bigger zoom levels for those features + */ + readonly dontEnforceMinZoom?: boolean, readonly registerTile?: (tile: TiledFeatureSource & Tiled) => void, readonly layer?: FilteredLayer } \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index e88a1d82d..6f815f48d 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -3,13 +3,29 @@ import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import TileHierarchy from "./TileHierarchy"; -import {Utils} from "../../../Utils"; import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; -import {BBox} from "../../GeoOperations"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class TiledFromLocalStorageSource implements TileHierarchy { public loadedTiles: Map = new Map(); + public static GetFreshnesses(layerId: string): Map { + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layerId + "-" + const freshnesses = new Map() + for (const key of Object.keys(localStorage)) { + if(!(key.startsWith(prefix) && key.endsWith("-time"))){ + continue + } + const index = Number(key.substring(prefix.length, key.length - "-time".length)) + const time = Number(localStorage.getItem(key)) + const freshness = new Date() + freshness.setTime(time) + freshnesses.set(index, freshness) + } + return freshnesses + } + constructor(layer: FilteredLayer, handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void, state: { @@ -17,17 +33,32 @@ export default class TiledFromLocalStorageSource implements TileHierarchy() const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" // @ts-ignore const indexes: number[] = Object.keys(localStorage) .filter(key => { - return key.startsWith(prefix) && !key.endsWith("-time"); + return key.startsWith(prefix) && !key.endsWith("-time") && !key.endsWith("-format"); }) .map(key => { return Number(key.substring(prefix.length)); }) + .filter(i => !isNaN(i)) - console.log("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Utils.tile_from_index(i).join("/")).join(", ")) + console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) + for (const index of indexes) { + + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" + index; + const version = localStorage.getItem(prefix + "-format") + if (version === undefined || version !== SaveTileToLocalStorageActor.formatVersion) { + // Invalid version! Remove this tile from local storage + localStorage.removeItem(prefix) + localStorage.removeItem(prefix+"-time") + localStorage.removeItem(prefix+"-format") + undefinedTiles.add(index) + console.log("Dropped old format tile", prefix) + } + } const zLevels = indexes.map(i => i % 100) const indexesSet = new Set(indexes) @@ -57,9 +88,9 @@ export default class TiledFromLocalStorageSource implements TileHierarchy Utils.tile_index(z, x, y)) - .filter(i => !self.loadedTiles.has(i) && indexesSet.has(i)) + const tileRange = Tiles.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest()) + const neededZ = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(z, x, y)) + .filter(i => !self.loadedTiles.has(i) && !undefinedTiles.has(i) && indexesSet.has(i)) needed.push(...neededZ) } @@ -70,8 +101,6 @@ export default class TiledFromLocalStorageSource implements TileHierarchy console.log("Tiles to load from localstorage:", t)) - neededTiles.addCallbackAndRunD(neededIndexes => { for (const neededIndex of neededIndexes) { // We load the features from localStorage @@ -84,12 +113,13 @@ export default class TiledFromLocalStorageSource implements TileHierarchy(features), name: "FromLocalStorage(" + key + ")", tileIndex: neededIndex, - bbox: BBox.fromTile(...Utils.tile_from_index(neededIndex)) + bbox: BBox.fromTileIndex(neededIndex) } handleFeatureSource(src, neededIndex) self.loadedTiles.set(neededIndex, src) } catch (e) { console.error("Could not load data tile from local storage due to", e) + undefinedTiles.add(neededIndex) } } diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index 66fd90053..3fa10f7a2 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -1,5 +1,5 @@ import * as turf from '@turf/turf' -import {Utils} from "../Utils"; +import {BBox} from "./BBox"; export class GeoOperations { @@ -8,7 +8,7 @@ export class GeoOperations { } /** - * Converts a GeoJSon feature to a point feature + * Converts a GeoJson feature to a point GeoJson feature * @param feature */ static centerpoint(feature: any) { @@ -378,112 +378,3 @@ export class GeoOperations { } -export class BBox { - - readonly maxLat: number; - readonly maxLon: number; - readonly minLat: number; - readonly minLon: number; - static global: BBox = new BBox([[-180, -90], [180, 90]]); - - constructor(coordinates) { - this.maxLat = Number.MIN_VALUE; - this.maxLon = Number.MIN_VALUE; - this.minLat = Number.MAX_VALUE; - this.minLon = Number.MAX_VALUE; - - - for (const coordinate of coordinates) { - this.maxLon = Math.max(this.maxLon, coordinate[0]); - this.maxLat = Math.max(this.maxLat, coordinate[1]); - this.minLon = Math.min(this.minLon, coordinate[0]); - this.minLat = Math.min(this.minLat, coordinate[1]); - } - this.check(); - } - - static fromLeafletBounds(bounds) { - return new BBox([[bounds.getWest(), bounds.getNorth()], [bounds.getEast(), bounds.getSouth()]]) - } - - static get(feature): BBox { - if (feature.bbox?.overlapsWith === undefined) { - const turfBbox: number[] = turf.bbox(feature) - feature.bbox = new BBox([[turfBbox[0], turfBbox[1]], [turfBbox[2], turfBbox[3]]]); - } - return feature.bbox; - } - - public overlapsWith(other: BBox) { - if (this.maxLon < other.minLon) { - return false; - } - if (this.maxLat < other.minLat) { - return false; - } - if (this.minLon > other.maxLon) { - return false; - } - return this.minLat <= other.maxLat; - - } - - public isContainedIn(other: BBox) { - if (this.maxLon > other.maxLon) { - return false; - } - if (this.maxLat > other.maxLat) { - return false; - } - if (this.minLon < other.minLon) { - return false; - } - if (this.minLat < other.minLat) { - return false - } - return true; - } - - private check() { - if (isNaN(this.maxLon) || isNaN(this.maxLat) || isNaN(this.minLon) || isNaN(this.minLat)) { - console.log(this); - throw "BBOX has NAN"; - } - } - - static fromTile(z: number, x: number, y: number) { - return new BBox(Utils.tile_bounds_lon_lat(z, x, y)) - } - - getEast() { - return this.maxLon - } - - getNorth() { - return this.maxLat - } - - getWest() { - return this.minLon - } - - getSouth() { - return this.minLat - } - - pad(factor: number) : BBox { - const latDiff = this.maxLat - this.minLat - const lat = (this.maxLat + this.minLat) / 2 - const lonDiff = this.maxLon - this.minLon - const lon = (this.maxLon + this.minLon) / 2 - return new BBox([[ - lon - lonDiff * factor, - lat - latDiff * factor - ], [lon + lonDiff * factor, - lat + latDiff * factor]]) - } - - toLeaflet() { - return [[this.minLat, this.minLon], [this.maxLat, this.maxLon]] - } -} \ No newline at end of file diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index e616e59e7..18589f635 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -1,9 +1,61 @@ import {Mapillary} from "./Mapillary"; -import {Wikimedia} from "./Wikimedia"; +import {WikimediaImageProvider} from "./WikimediaImageProvider"; import {Imgur} from "./Imgur"; +import GenericImageProvider from "./GenericImageProvider"; +import {UIEventSource} from "../UIEventSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import {WikidataImageProvider} from "./WikidataImageProvider"; +/** + * A generic 'from the interwebz' image picker, without attribution + */ export default class AllImageProviders { - public static ImageAttributionSource = [Imgur.singleton, Mapillary.singleton, Wikimedia.singleton] + public static ImageAttributionSource: ImageProvider[] = [ + Imgur.singleton, + Mapillary.singleton, + WikidataImageProvider.singleton, + WikimediaImageProvider.singleton, + new GenericImageProvider([].concat(...Imgur.defaultValuePrefix, WikimediaImageProvider.commonsPrefix))] + + + private static _cache: Map> = new Map>() + + public static LoadImagesFor(tags: UIEventSource, imagePrefix?: string): UIEventSource { + const id = tags.data.id + if (id === undefined) { + return undefined; + } + + const cached = this._cache.get(tags.data.id) + if (cached !== undefined) { + return cached + } + + + const source = new UIEventSource([]) + this._cache.set(id, source) + const allSources = [] + for (const imageProvider of AllImageProviders.ImageAttributionSource) { + const singleSource = imageProvider.GetRelevantUrls(tags, { + prefixes: imagePrefix !== undefined ? [imagePrefix] : undefined + }) + allSources.push(singleSource) + singleSource.addCallbackAndRunD(_ => { + const all : ProvidedImage[] = [].concat(...allSources.map(source => source.data)) + const uniq = [] + const seen = new Set() + for (const img of all) { + if(seen.has(img.url)){ + continue + } + seen.add(img.url) + uniq.push(img) + } + source.setData(uniq) + }) + } + return source; + } } \ No newline at end of file diff --git a/Logic/ImageProviders/GenericImageProvider.ts b/Logic/ImageProviders/GenericImageProvider.ts new file mode 100644 index 000000000..170829fe0 --- /dev/null +++ b/Logic/ImageProviders/GenericImageProvider.ts @@ -0,0 +1,36 @@ +import ImageProvider, {ProvidedImage} from "./ImageProvider"; + +export default class GenericImageProvider extends ImageProvider { + public defaultKeyPrefixes: string[] = ["image"]; + + private readonly _valuePrefixBlacklist: string[]; + + public constructor(valuePrefixBlacklist: string[]) { + super(); + this._valuePrefixBlacklist = valuePrefixBlacklist; + } + + + protected DownloadAttribution(url: string) { + return undefined + } + + async ExtractUrls(key: string, value: string): Promise[]> { + + if (this._valuePrefixBlacklist.some(prefix => value.startsWith(prefix))) { + return [] + } + + return [Promise.resolve({ + key: key, + url: value, + provider: this + })] + } + + SourceIcon(backlinkSource?: string) { + return undefined; + } + + +} \ No newline at end of file diff --git a/Logic/ImageProviders/ImageAttributionSource.ts b/Logic/ImageProviders/ImageAttributionSource.ts deleted file mode 100644 index 7841c899b..000000000 --- a/Logic/ImageProviders/ImageAttributionSource.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {UIEventSource} from "../UIEventSource"; -import {LicenseInfo} from "./Wikimedia"; -import BaseUIElement from "../../UI/BaseUIElement"; - - -export default abstract class ImageAttributionSource { - - private _cache = new Map>() - - GetAttributionFor(url: string): UIEventSource { - const cached = this._cache.get(url); - if (cached !== undefined) { - return cached; - } - const src = this.DownloadAttribution(url) - this._cache.set(url, src) - return src; - } - - - public abstract SourceIcon(backlinkSource?: string): BaseUIElement; - - /*Converts a value to a URL. Can return null if not applicable*/ - public PrepareUrl(value: string): string | UIEventSource{ - return value; - } - - protected abstract DownloadAttribution(url: string): UIEventSource; - -} \ No newline at end of file diff --git a/Logic/ImageProviders/ImageProvider.ts b/Logic/ImageProviders/ImageProvider.ts new file mode 100644 index 000000000..67154d945 --- /dev/null +++ b/Logic/ImageProviders/ImageProvider.ts @@ -0,0 +1,64 @@ +import {UIEventSource} from "../UIEventSource"; +import BaseUIElement from "../../UI/BaseUIElement"; +import {LicenseInfo} from "./LicenseInfo"; + +export interface ProvidedImage { + url: string, key: string, provider: ImageProvider +} + +export default abstract class ImageProvider { + + protected abstract readonly defaultKeyPrefixes : string[] + + private _cache = new Map>() + + GetAttributionFor(url: string): UIEventSource { + const cached = this._cache.get(url); + if (cached !== undefined) { + return cached; + } + const src =UIEventSource.FromPromise(this.DownloadAttribution(url)) + this._cache.set(url, src) + return src; + } + + public abstract SourceIcon(backlinkSource?: string): BaseUIElement; + + protected abstract DownloadAttribution(url: string): Promise; + + /** + * Given a properies object, maps it onto _all_ the available pictures for this imageProvider + */ + public GetRelevantUrls(allTags: UIEventSource, options?: { + prefixes?: string[] + }):UIEventSource { + const prefixes = options?.prefixes ?? this.defaultKeyPrefixes + const relevantUrls = new UIEventSource<{ url: string; key: string; provider: ImageProvider }[]>([]) + const seenValues = new Set() + allTags.addCallbackAndRunD(tags => { + for (const key in tags) { + if(!prefixes.some(prefix => key.startsWith(prefix))){ + continue + } + const value = tags[key] + if(seenValues.has(value)){ + continue + } + seenValues.add(value) + + this.ExtractUrls(key, value).then(promises => { + for (const promise of promises) { + promise.then(providedImage => { + relevantUrls.data.push(providedImage) + relevantUrls.ping() + }) + } + }) + } + }) + return relevantUrls + } + + public abstract ExtractUrls(key: string, value: string) : Promise[]>; + +} \ No newline at end of file diff --git a/Logic/ImageProviders/Imgur.ts b/Logic/ImageProviders/Imgur.ts index 4325d3e37..289dad1f8 100644 --- a/Logic/ImageProviders/Imgur.ts +++ b/Logic/ImageProviders/Imgur.ts @@ -1,11 +1,14 @@ -// @ts-ignore import $ from "jquery" -import {LicenseInfo} from "./Wikimedia"; -import ImageAttributionSource from "./ImageAttributionSource"; -import {UIEventSource} from "../UIEventSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; import BaseUIElement from "../../UI/BaseUIElement"; +import {Utils} from "../../Utils"; +import Constants from "../../Models/Constants"; +import {LicenseInfo} from "./LicenseInfo"; -export class Imgur extends ImageAttributionSource { +export class Imgur extends ImageProvider { + + public static readonly defaultValuePrefix = ["https://i.imgur.com"] + public readonly defaultKeyPrefixes: string[] = ["image"]; public static readonly singleton = new Imgur(); @@ -86,51 +89,39 @@ export class Imgur extends ImageAttributionSource { return undefined; } - protected DownloadAttribution(url: string): UIEventSource { - const src = new UIEventSource(undefined) - - + protected DownloadAttribution: (url: string) => Promise = async (url: string) => { const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0]; const apiUrl = 'https://api.imgur.com/3/image/' + hash; - const apiKey = '7070e7167f0a25a'; + const response = await Utils.downloadJson(apiUrl, {Authorization: 'Client-ID ' + Constants.ImgurApiKey}) - const settings = { - async: true, - crossDomain: true, - processData: false, - contentType: false, - type: 'GET', - url: apiUrl, - headers: { - Authorization: 'Client-ID ' + apiKey, - Accept: 'application/json', - }, - }; - // @ts-ignore - $.ajax(settings).done(function (response) { - const descr: string = response.data.description ?? ""; - const data: any = {}; - for (const tag of descr.split("\n")) { - const kv = tag.split(":"); - const k = kv[0]; - data[k] = kv[1].replace("\r", ""); - } + const descr: string = response.data.description ?? ""; + const data: any = {}; + for (const tag of descr.split("\n")) { + const kv = tag.split(":"); + const k = kv[0]; + data[k] = kv[1]?.replace("\r", ""); + } - const licenseInfo = new LicenseInfo(); + const licenseInfo = new LicenseInfo(); - licenseInfo.licenseShortName = data.license; - licenseInfo.artist = data.author; + licenseInfo.licenseShortName = data.license; + licenseInfo.artist = data.author; - src.setData(licenseInfo) - - }).fail((reason) => { - console.log("Getting metadata from to IMGUR failed", reason) - }); - - return src; + return licenseInfo } + public async ExtractUrls(key: string, value: string): Promise[]> { + if (Imgur.defaultValuePrefix.some(prefix => value.startsWith(prefix))) { + return [Promise.resolve({ + url: value, + key: key, + provider: this + })] + } + return [] + } + } \ No newline at end of file diff --git a/Logic/ImageProviders/LicenseInfo.ts b/Logic/ImageProviders/LicenseInfo.ts new file mode 100644 index 000000000..b5954693c --- /dev/null +++ b/Logic/ImageProviders/LicenseInfo.ts @@ -0,0 +1,10 @@ +export class LicenseInfo { + artist: string = ""; + license: string = ""; + licenseShortName: string = ""; + usageTerms: string = ""; + attributionRequired: boolean = false; + copyrighted: boolean = false; + credit: string = ""; + description: string = ""; +} \ No newline at end of file diff --git a/Logic/ImageProviders/Mapillary.ts b/Logic/ImageProviders/Mapillary.ts index 3f992dbce..45342bc14 100644 --- a/Logic/ImageProviders/Mapillary.ts +++ b/Logic/ImageProviders/Mapillary.ts @@ -1,18 +1,18 @@ -import {LicenseInfo} from "./Wikimedia"; -import ImageAttributionSource from "./ImageAttributionSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; import BaseUIElement from "../../UI/BaseUIElement"; import {UIEventSource} from "../UIEventSource"; import Svg from "../../Svg"; import {Utils} from "../../Utils"; +import {LicenseInfo} from "./LicenseInfo"; +import Constants from "../../Models/Constants"; -export class Mapillary extends ImageAttributionSource { +export class Mapillary extends ImageProvider { - public static readonly singleton = new Mapillary(); + defaultKeyPrefixes = ["mapillary"] - private static readonly v4_cached_urls = new Map>(); + public static readonly singleton = new Mapillary(); - private static readonly client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' - private static readonly client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" + private static readonly v4_cached_urls = new Map>(); private constructor() { super(); @@ -23,8 +23,8 @@ export class Mapillary extends ImageAttributionSource { isApiv4?: boolean } { if (value.startsWith("https://a.mapillary.com")) { - const key = value.substring(0, value.lastIndexOf("?")).substring(value.lastIndexOf("/") + 1) - return {key:key, isApiv4: !isNaN(Number(key))}; + const key = value.substring(0, value.lastIndexOf("?")).substring(value.lastIndexOf("/") + 1) + return {key: key, isApiv4: !isNaN(Number(key))}; } const newApiFormat = value.match(/https?:\/\/www.mapillary.com\/app\/\?pKey=([0-9]*)/) if (newApiFormat !== null) { @@ -32,11 +32,11 @@ export class Mapillary extends ImageAttributionSource { } const mapview = value.match(/https?:\/\/www.mapillary.com\/map\/im\/(.*)/) - if(mapview !== null){ + if (mapview !== null) { const key = mapview[1] - return {key:key, isApiv4: !isNaN(Number(key))}; + return {key: key, isApiv4: !isNaN(Number(key))}; } - + if (value.toLowerCase().startsWith("https://www.mapillary.com/map/im/")) { // Extract the key of the image @@ -56,54 +56,56 @@ export class Mapillary extends ImageAttributionSource { return Svg.mapillary_svg(); } - PrepareUrl(value: string): string | UIEventSource { - const keyV = Mapillary.ExtractKeyFromURL(value) - if (!keyV.isApiv4) { - return `https://images.mapillary.com/${keyV.key}/thumb-640.jpg?client_id=${Mapillary.client_token_v3}` - } else { - const key = keyV.key; - if(Mapillary.v4_cached_urls.has(key)){ - return Mapillary.v4_cached_urls.get(key) - } - - const metadataUrl ='https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Mapillary.client_token_v4; - const source = new UIEventSource(undefined) - Mapillary.v4_cached_urls.set(key, source) - Utils.downloadJson(metadataUrl).then( - json => { - console.warn("Got response on mapillary image", json, json["thumb_1024_url"]) - return source.setData(json["thumb_1024_url"]); - } - ) - return source - } + async ExtractUrls(key: string, value: string): Promise[]> { + return [this.PrepareUrlAsync(key, value)] } - protected DownloadAttribution(url: string): UIEventSource { + private async PrepareUrlAsync(key: string, value: string): Promise { + const keyV = Mapillary.ExtractKeyFromURL(value) + if (!keyV.isApiv4) { + const url = `https://images.mapillary.com/${keyV.key}/thumb-640.jpg?client_id=${Constants.mapillary_client_token_v3}` + return { + url: url, + provider: this, + key: key + } + } else { + const key = keyV.key; + const metadataUrl = 'https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Constants.mapillary_client_token_v4; + const source = new UIEventSource(undefined) + Mapillary.v4_cached_urls.set(key, source) + const response = await Utils.downloadJson(metadataUrl) + const url = response["thumb_1024_url"]; + return { + url: url, + provider: this, + key: key + } + } + } + + protected async DownloadAttribution(url: string): Promise { const keyV = Mapillary.ExtractKeyFromURL(url) - if(keyV.isApiv4){ + if (keyV.isApiv4) { const license = new LicenseInfo() license.artist = "Contributor name unavailable"; license.license = "CC BY-SA 4.0"; // license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; license.attributionRequired = true; - return new UIEventSource(license) - + return license + } const key = keyV.key - - const metadataURL = `https://a.mapillary.com/v3/images/${key}?client_id=TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2` - const source = new UIEventSource(undefined) - Utils.downloadJson(metadataURL).then(data => { - const license = new LicenseInfo(); - license.artist = data.properties?.username; - license.licenseShortName = "CC BY-SA 4.0"; - license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; - license.attributionRequired = true; - source.setData(license); - }) - return source + const metadataURL = `https://a.mapillary.com/v3/images/${key}?client_id=TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2` + const data = await Utils.downloadJson(metadataURL) + const license = new LicenseInfo(); + license.artist = data.properties?.username; + license.licenseShortName = "CC BY-SA 4.0"; + license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; + license.attributionRequired = true; + + return license } } \ No newline at end of file diff --git a/Logic/ImageProviders/WikidataImageProvider.ts b/Logic/ImageProviders/WikidataImageProvider.ts new file mode 100644 index 000000000..3bb7d3c91 --- /dev/null +++ b/Logic/ImageProviders/WikidataImageProvider.ts @@ -0,0 +1,51 @@ +import {Utils} from "../../Utils"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import BaseUIElement from "../../UI/BaseUIElement"; +import Svg from "../../Svg"; +import {WikimediaImageProvider} from "./WikimediaImageProvider"; + +export class WikidataImageProvider extends ImageProvider { + + public SourceIcon(backlinkSource?: string): BaseUIElement { + throw Svg.wikidata_svg(); + } + + public static readonly singleton = new WikidataImageProvider() + public readonly defaultKeyPrefixes = ["wikidata"] + + private constructor() { + super() + } + + protected DownloadAttribution(url: string): Promise { + throw new Error("Method not implemented; shouldn't be needed!"); + } + + public async ExtractUrls(key: string, value: string): Promise[]> { + const wikidataUrl = "https://www.wikidata.org/wiki/" + if (value.startsWith(wikidataUrl)) { + value = value.substring(wikidataUrl.length) + } + if (!value.startsWith("Q")) { + value = "Q" + value + } + const url = "https://www.wikidata.org/wiki/Special:EntityData/" + value + ".json"; + const response = await Utils.downloadJson(url) + const entity = response.entities[value]; + const commons = entity.sitelinks.commonswiki; + // P18 is the claim 'depicted in this image' + const image = entity.claims.P18?.[0]?.mainsnak?.datavalue?.value; + const allImages = [] + if (image !== undefined) { + // We found a 'File://' + const promises = await WikimediaImageProvider.singleton.ExtractUrls(key, image) + allImages.push(...promises) + } + if (commons !== undefined) { + const promises = await WikimediaImageProvider.singleton.ExtractUrls(commons, image) + allImages.push(...promises) + } + return allImages + } + +} \ No newline at end of file diff --git a/Logic/ImageProviders/Wikimedia.ts b/Logic/ImageProviders/Wikimedia.ts deleted file mode 100644 index 32c762523..000000000 --- a/Logic/ImageProviders/Wikimedia.ts +++ /dev/null @@ -1,195 +0,0 @@ -import ImageAttributionSource from "./ImageAttributionSource"; -import BaseUIElement from "../../UI/BaseUIElement"; -import Svg from "../../Svg"; -import {UIEventSource} from "../UIEventSource"; -import Link from "../../UI/Base/Link"; -import {Utils} from "../../Utils"; - -/** - * This module provides endpoints for wikipedia/wikimedia and others - */ -export class Wikimedia extends ImageAttributionSource { - - - public static readonly singleton = new Wikimedia(); - - private constructor() { - super(); - } - - - static ImageNameToUrl(filename: string, width: number = 500, height: number = 200): string { - filename = encodeURIComponent(filename); - return "https://commons.wikimedia.org/wiki/Special:FilePath/" + filename + "?width=" + width + "&height=" + height; - } - - static GetCategoryFiles(categoryName: string, handleCategory: ((ImagesInCategory: ImagesInCategory) => void), - alreadyLoaded = 0, - continueParameter: { k: string, param: string } = undefined) { - if (categoryName === undefined || categoryName === null || categoryName === "") { - return; - } - // @ts-ignore - if (!categoryName.startsWith("Category:")) { - categoryName = "Category:" + categoryName; - } - let url = "https://commons.wikimedia.org/w/api.php?" + - "action=query&list=categorymembers&format=json&" + - "&origin=*" + - "&cmtitle=" + encodeURIComponent(categoryName); - if (continueParameter !== undefined) { - url = url + "&" + continueParameter.k + "=" + continueParameter.param; - } - const self = this; - console.log("Loading a wikimedia category: ", url) - Utils.downloadJson(url).then((response) => { - let imageOverview = new ImagesInCategory(); - let members = response.query?.categorymembers; - if (members === undefined) { - members = []; - } - - for (const member of members) { - imageOverview.images.push(member.title); - } - console.log("Got images! ", imageOverview) - if (response.continue === undefined) { - handleCategory(imageOverview); - return; - } - - if (alreadyLoaded > 10) { - console.log(`Recursive wikimedia category load stopped for ${categoryName} - got already enough images now (${alreadyLoaded})`) - handleCategory(imageOverview) - return; - } - - self.GetCategoryFiles(categoryName, - (recursiveImages) => { - recursiveImages.images.push(...imageOverview.images); - handleCategory(recursiveImages); - }, - alreadyLoaded + 10, - {k: "cmcontinue", param: response.continue.cmcontinue}) - - }); - } - - static GetWikiData(id: number, handleWikidata: ((Wikidata) => void)) { - const url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json"; - Utils.downloadJson(url).then(response => { - const entity = response.entities["Q" + id]; - const commons = entity.sitelinks.commonswiki; - const wd = new Wikidata(); - wd.commonsWiki = commons?.title; - - // P18 is the claim 'depicted in this image' - const image = entity.claims.P18?.[0]?.mainsnak?.datavalue?.value; - if (image) { - wd.image = "File:" + image; - } - handleWikidata(wd); - }); - } - - private static ExtractFileName(url: string) { - if (!url.startsWith("http")) { - return url; - } - const path = new URL(url).pathname - return path.substring(path.lastIndexOf("/") + 1); - - } - - SourceIcon(backlink: string): BaseUIElement { - const img = Svg.wikimedia_commons_white_svg() - .SetStyle("width:2em;height: 2em"); - if (backlink === undefined) { - return img - } - - - return new Link(Svg.wikimedia_commons_white_img, - `https://commons.wikimedia.org/wiki/${backlink}`, true) - - - } - - PrepareUrl(value: string): string { - - if (value.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { - return value; - } - return Wikimedia.ImageNameToUrl(value, 500, 400) - .replace(/'/g, '%27'); - } - - protected DownloadAttribution(filename: string): UIEventSource { - - const source = new UIEventSource(undefined); - - filename = Wikimedia.ExtractFileName(filename) - - if (filename === "") { - return source; - } - - const url = "https://en.wikipedia.org/w/" + - "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + - "titles=" + filename + - "&format=json&origin=*"; - Utils.downloadJson(url).then( - data => { - const licenseInfo = new LicenseInfo(); - const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; - if (license === undefined) { - console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") - source.setData(null) - return; - } - - licenseInfo.artist = license.Artist?.value; - licenseInfo.license = license.License?.value; - licenseInfo.copyrighted = license.Copyrighted?.value; - licenseInfo.attributionRequired = license.AttributionRequired?.value; - licenseInfo.usageTerms = license.UsageTerms?.value; - licenseInfo.licenseShortName = license.LicenseShortName?.value; - licenseInfo.credit = license.Credit?.value; - licenseInfo.description = license.ImageDescription?.value; - source.setData(licenseInfo); - } - ) - - return source; - - } - - -} - -export class Wikidata { - - commonsWiki: string; - image: string; - -} - -export class ImagesInCategory { - // Filenames of relevant images - images: string[] = []; -} - -export class LicenseInfo { - - - artist: string = ""; - license: string = ""; - licenseShortName: string = ""; - usageTerms: string = ""; - attributionRequired: boolean = false; - copyrighted: boolean = false; - credit: string = ""; - description: string = ""; - - -} \ No newline at end of file diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts new file mode 100644 index 000000000..b8940a520 --- /dev/null +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -0,0 +1,170 @@ +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import BaseUIElement from "../../UI/BaseUIElement"; +import Svg from "../../Svg"; +import Link from "../../UI/Base/Link"; +import {Utils} from "../../Utils"; +import {LicenseInfo} from "./LicenseInfo"; + +/** + * This module provides endpoints for wikimedia and others + */ +export class WikimediaImageProvider extends ImageProvider { + + + private readonly commons_key = "wikimedia_commons" + public readonly defaultKeyPrefixes = [this.commons_key,"image"] + public static readonly singleton = new WikimediaImageProvider(); + public static readonly commonsPrefix = "https://commons.wikimedia.org/wiki/" + + private constructor() { + super(); + } + + /** + * Recursively walks a wikimedia commons category in order to search for (image) files + * Returns (a promise of) a list of URLS + * @param categoryName The name of the wikimedia category + * @param maxLoad: the maximum amount of images to return + * @param continueParameter: if the page indicates that more pages should be loaded, this uses a token to continue. Provided by wikimedia + */ + private static async GetImagesInCategory(categoryName: string, + maxLoad = 10, + continueParameter: string = undefined): Promise { + if (categoryName === undefined || categoryName === null || categoryName === "") { + return []; + } + if (!categoryName.startsWith("Category:")) { + categoryName = "Category:" + categoryName; + } + + let url = "https://commons.wikimedia.org/w/api.php?" + + "action=query&list=categorymembers&format=json&" + + "&origin=*" + + "&cmtitle=" + encodeURIComponent(categoryName); + if (continueParameter !== undefined) { + url = `${url}&cmcontinue=${continueParameter}`; + } + console.log("Loading a wikimedia category: ", url) + const response = await Utils.downloadJson(url) + const members = response.query?.categorymembers ?? []; + const imageOverview: string[] = members.map(member => member.title); + + if (response.continue === undefined) { + // We are done crawling through the category - no continuation in sight + return imageOverview; + } + + if (maxLoad - imageOverview.length <= 0) { + console.log(`Recursive wikimedia category load stopped for ${categoryName}`) + return imageOverview; + } + + // We do have a continue token - let's load the next page + const recursive = await this.GetImagesInCategory(categoryName, maxLoad - imageOverview.length, response.continue.cmcontinue) + imageOverview.push(...recursive) + return imageOverview + } + + private static ExtractFileName(url: string) { + if (!url.startsWith("http")) { + return url; + } + const path = new URL(url).pathname + return path.substring(path.lastIndexOf("/") + 1); + + } + + SourceIcon(backlink: string): BaseUIElement { + const img = Svg.wikimedia_commons_white_svg() + .SetStyle("width:2em;height: 2em"); + if (backlink === undefined) { + return img + } + + + return new Link(Svg.wikimedia_commons_white_img, + `https://commons.wikimedia.org/wiki/${backlink}`, true) + + + } + + private PrepareUrl(value: string): string { + + if (value.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { + return value; + } + return (`https://commons.wikimedia.org/wiki/Special:FilePath/${encodeURIComponent(value)}?width=500&height=400`) + } + + protected async DownloadAttribution(filename: string): Promise { + filename = WikimediaImageProvider.ExtractFileName(filename) + + if (filename === "") { + return undefined; + } + + const url = "https://en.wikipedia.org/w/" + + "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + + "titles=" + filename + + "&format=json&origin=*"; + const data = await Utils.downloadJson(url) + const licenseInfo = new LicenseInfo(); + const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; + if (license === undefined) { + console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") + return undefined; + } + + licenseInfo.artist = license.Artist?.value; + licenseInfo.license = license.License?.value; + licenseInfo.copyrighted = license.Copyrighted?.value; + licenseInfo.attributionRequired = license.AttributionRequired?.value; + licenseInfo.usageTerms = license.UsageTerms?.value; + licenseInfo.licenseShortName = license.LicenseShortName?.value; + licenseInfo.credit = license.Credit?.value; + licenseInfo.description = license.ImageDescription?.value; + return licenseInfo; + + } + + private async UrlForImage(image: string): Promise { + if (!image.startsWith("File:")) { + image = "File:" + image + } + return {url: this.PrepareUrl(image), key: undefined, provider: this} + } + + public async ExtractUrls(key: string, value: string): Promise[]> { + + if(key !== this.commons_key && !value.startsWith(WikimediaImageProvider.commonsPrefix)){ + return [] + } + + if (value.startsWith(WikimediaImageProvider.commonsPrefix)) { + value = value.substring(WikimediaImageProvider.commonsPrefix.length) + } else if (value.startsWith("https://upload.wikimedia.org")) { + const result: ProvidedImage = { + key: undefined, + url: value, + provider: this + } + return [Promise.resolve(result)] + } + if (value.startsWith("Category:")) { + const urls = await WikimediaImageProvider.GetImagesInCategory(value) + return urls.map(image => this.UrlForImage(image)) + } + if (value.startsWith("File:")) { + return [this.UrlForImage(value)] + } + if (value.startsWith("http")) { + // PRobably an error + return [] + } + // We do a last effort and assume this is a file + return [this.UrlForImage("File:" + value)] + } + + +} + diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 5745fa4ad..ee4209f4a 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -2,6 +2,7 @@ import SimpleMetaTagger from "./SimpleMetaTagger"; import {ExtraFuncParams, ExtraFunction} from "./ExtraFunction"; import {UIEventSource} from "./UIEventSource"; import LayerConfig from "../Models/ThemeConfig/LayerConfig"; +import State from "../State"; /** @@ -20,50 +21,68 @@ export default class MetaTagging { * The given features should be part of the given layer */ public static addMetatags(features: { feature: any; freshness: Date }[], - params: ExtraFuncParams, - layer: LayerConfig, - options?: { - includeDates?: true | boolean, - includeNonDates?: true | boolean - }) { + params: ExtraFuncParams, + layer: LayerConfig, + options?: { + includeDates?: true | boolean, + includeNonDates?: true | boolean + }) { if (features === undefined || features.length === 0) { return; } - for (const metatag of SimpleMetaTagger.metatags) { - try { + const metatagsToApply: SimpleMetaTagger [] = [] + for (const metatag of SimpleMetaTagger.metatags) { if (metatag.includesDates) { if (options.includeDates ?? true) { - metatag.addMetaTags(features); + metatagsToApply.push(metatag) } } else { if (options.includeNonDates ?? true) { - metatag.addMetaTags(features); + metatagsToApply.push(metatag) } } - - } catch (e) { - console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e) } - } - // The functions - per layer - which add the new keys + // The calculated functions - per layer - which add the new keys const layerFuncs = this.createRetaggingFunc(layer) - if (layerFuncs !== undefined) { - for (const feature of features) { - try { - layerFuncs(params, feature.feature) - } catch (e) { - console.error(e) + for (let i = 0; i < features.length; i++) { + const ff = features[i]; + const feature = ff.feature + const freshness = ff.freshness + let somethingChanged = false + for (const metatag of metatagsToApply) { + try { + if(!metatag.keys.some(key => feature.properties[key] === undefined)){ + // All keys are already defined, we probably already ran this one + continue + } + somethingChanged = somethingChanged || metatag.applyMetaTagsOnFeature(feature, freshness) + } catch (e) { + console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e, e.stack) + } + } + + if(layerFuncs !== undefined){ + try { + layerFuncs(params, feature) + } catch (e) { + console.error(e) + } + somethingChanged = true + } + + if(somethingChanged){ + State.state.allElements.getEventSourceById(feature.properties.id).ping() } } - } } + private static createRetaggingFunc(layer: LayerConfig): ((params: ExtraFuncParams, feature: any) => void) { const calculatedTags: [string, string][] = layer.calculatedTags; @@ -106,7 +125,7 @@ export default class MetaTagging { feature.properties[key] = result; } catch (e) { if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { - console.warn("Could not calculate a calculated tag defined by " + code + " due to " + e + ". This is code defined in the theme. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e) + console.warn("Could not calculate a calculated tag defined by " + code + " due to " + e + ". This is code defined in the theme. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e,e.stack) MetaTagging.errorPrintCount++; if (MetaTagging.errorPrintCount == MetaTagging.stopErrorOutputAt) { console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now") @@ -131,6 +150,7 @@ export default class MetaTagging { for (const f of functions) { f(params, feature); } + State.state.allElements.getEventSourceById(feature.properties.id).ping(); } catch (e) { console.error("While calculating a tag value: ", e) } diff --git a/Logic/Osm/Actions/DeleteAction.ts b/Logic/Osm/Actions/DeleteAction.ts index 25542bf18..68919bd12 100644 --- a/Logic/Osm/Actions/DeleteAction.ts +++ b/Logic/Osm/Actions/DeleteAction.ts @@ -62,7 +62,7 @@ export default class DeleteAction { } State.state.osmConnection.changesetHandler.DeleteElement( obj, - State.state.layoutToUse.data, + State.state.layoutToUse, reason, State.state.allElements, () => { diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 83545b30a..570bf553b 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -14,7 +14,7 @@ import {LocalStorageSource} from "../Web/LocalStorageSource"; export class Changes { - private _nextId : number = -1; // Newly assigned ID's are negative + private _nextId: number = -1; // Newly assigned ID's are negative public readonly name = "Newly added features" /** * All the newly created features as featureSource + all the modified features @@ -31,7 +31,10 @@ export class Changes { // We keep track of all changes just as well this.allChanges.setData([...this.pendingChanges.data]) // If a pending change contains a negative ID, we save that - this._nextId = Math.min(-1, ...this.pendingChanges.data?.map(pch => pch.id) ?? []) + this._nextId = Math.min(-1, ...this.pendingChanges.data?.map(pch => pch.id) ?? []) + + // Note: a changeset might be reused which was opened just before and might have already used some ids + // This doesn't matter however, as the '-1' is per piecewise upload, not global per changeset } private static createChangesetFor(csId: string, @@ -90,74 +93,69 @@ export class Changes { if (this.pendingChanges.data.length === 0) { return; } - if (this.isUploading.data) { console.log("Is already uploading... Abort") return; } - - this.isUploading.setData(true) + this.flushChangesAsync(flushreason) + .then(_ => { + this.isUploading.setData(false) + console.log("Changes flushed!"); + }) + .catch(e => { + this.isUploading.setData(false) + console.error("Flushing changes failed due to", e); + }) + } + + private async flushChangesAsync(flushreason: string = undefined): Promise { console.log("Beginning upload... " + flushreason ?? ""); // At last, we build the changeset and upload const self = this; const pending = self.pendingChanges.data; const neededIds = Changes.GetNeededIds(pending) - console.log("Needed ids", neededIds) - OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => { - console.log("Got the fresh objects!", osmObjects, "pending: ", pending) - try { - - - 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") - self.pendingChanges.setData([]) - self.isUploading.setData(false) - return true; // Unregister the callback - } - - - State.state.osmConnection.UploadChangeset( - State.state.layoutToUse.data, - State.state.allElements, - (csId) => Changes.createChangesetFor(csId, changes), - () => { - console.log("Upload successfull!") - self.pendingChanges.setData([]); - self.isUploading.setData(false) - }, - () => { - console.log("Upload failed - trying again later") - return self.isUploading.setData(false); - } // Failed - mark to try again - ) - } catch (e) { - console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e) + const osmObjects = await Promise.all(neededIds.map(id => OsmObject.DownloadObjectAsync(id))); + console.log("Got the fresh objects!", osmObjects, "pending: ", pending) + try { + 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") self.pendingChanges.setData([]) self.isUploading.setData(false) } - return true; - }); + await State.state.osmConnection.UploadChangeset( + State.state.layoutToUse, + State.state.allElements, + (csId) => Changes.createChangesetFor(csId, changes), + ) + + console.log("Upload successfull!") + this.pendingChanges.setData([]); + this.isUploading.setData(false) + + } catch (e) { + console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e) + self.pendingChanges.setData([]) + self.isUploading.setData(false) + } } - public applyAction(action: OsmChangeAction) { - action.Perform(this).then(changes => { - console.log("Received changes:", changes) - this.pendingChanges.data.push(...changes); - this.pendingChanges.ping(); - this.allChanges.data.push(...changes) - this.allChanges.ping() - }) + public async applyAction(action: OsmChangeAction): Promise { + const changes = await action.Perform(this) + console.log("Received changes:", changes) + this.pendingChanges.data.push(...changes); + this.pendingChanges.ping(); + this.allChanges.data.push(...changes) + this.allChanges.ping() } private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): { @@ -311,4 +309,8 @@ export class Changes { return result } + + public registerIdRewrites(mappings: Map): void { + + } } \ No newline at end of file diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index dcf0d135a..aae51d4ee 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -8,15 +8,23 @@ import Locale from "../../UI/i18n/Locale"; import Constants from "../../Models/Constants"; import {OsmObject} from "./OsmObject"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {Changes} from "./Changes"; export class ChangesetHandler { public readonly currentChangeset: UIEventSource; + private readonly allElements: ElementStorage; + private readonly changes: Changes; private readonly _dryRun: boolean; private readonly userDetails: UIEventSource; private readonly auth: any; - constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, auth) { + constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, + allElements: ElementStorage, + changes: Changes, + auth) { + this.allElements = allElements; + this.changes = changes; this._dryRun = dryRun; this.userDetails = osmConnection.userDetails; this.auth = auth; @@ -27,35 +35,55 @@ export class ChangesetHandler { } } - private static parseUploadChangesetResponse(response: XMLDocument, allElements: ElementStorage): void { + private handleIdRewrite(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; + } + + const newId = parseInt(node.attributes.new_id.value); + const result: [string, string] = [type + "/" + oldId, type + "/" + newId] + if (!(oldId !== undefined && newId !== undefined && + !isNaN(oldId) && !isNaN(newId))) { + return undefined; + } + if (oldId == newId) { + return undefined; + } + console.log("Rewriting id: ", type + "/" + oldId, "-->", type + "/" + newId); + const element = this.allElements.getEventSourceById("node/" + oldId); + 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; + } + + private parseUploadChangesetResponse(response: XMLDocument): void { const nodes = response.getElementsByTagName("node"); + const mappings = new Map() // @ts-ignore for (const node of nodes) { - const oldId = parseInt(node.attributes.old_id.value); - if (node.attributes.new_id === undefined) { - // We just removed this point! - const element = allElements.getEventSourceById("node/" + oldId); - element.data._deleted = "yes" - element.ping(); - continue; + const mapping = this.handleIdRewrite(node, "node") + if (mapping !== undefined) { + mappings.set(mapping[0], mapping[1]) } - - const newId = parseInt(node.attributes.new_id.value); - if (oldId !== undefined && newId !== undefined && - !isNaN(oldId) && !isNaN(newId)) { - if (oldId == newId) { - continue; - } - console.log("Rewriting id: ", oldId, "-->", newId); - const element = allElements.getEventSourceById("node/" + oldId); - element.data.id = "node/" + newId; - allElements.addElementById("node/" + newId, element); - element.ping(); - - } - - } + + const ways = response.getElementsByTagName("way"); + // @ts-ignore + for (const way of ways) { + const mapping = this.handleIdRewrite(way, "way") + if (mapping !== undefined) { + mappings.set(mapping[0], mapping[1]) + } + } + this.changes.registerIdRewrites(mappings) + } /** @@ -68,13 +96,9 @@ export class ChangesetHandler { * If 'dryrun' is specified, the changeset XML will be printed to console instead of being uploaded * */ - public UploadChangeset( + public async UploadChangeset( layout: LayoutConfig, - allElements: ElementStorage, - generateChangeXML: (csid: string) => string, - whenDone: (csId: string) => void, - onFail: () => void) { - + generateChangeXML: (csid: string) => string): Promise { if (this.userDetails.data.csCount == 0) { // The user became a contributor! this.userDetails.data.csCount = 1; @@ -84,46 +108,36 @@ export class ChangesetHandler { if (this._dryRun) { const changesetXML = generateChangeXML("123456"); console.log(changesetXML); - whenDone("123456") return; } - const self = this; - if (this.currentChangeset.data === undefined || this.currentChangeset.data === "") { // We have to open a new changeset - this.OpenChangeset(layout, (csId) => { + try { + const csId = await this.OpenChangeset(layout) this.currentChangeset.setData(csId); const changeset = generateChangeXML(csId); - console.log(changeset); - self.AddChange(csId, changeset, - allElements, - whenDone, - (e) => { - console.error("UPLOADING FAILED!", e) - onFail() - } - ) - }, { - onFail: onFail - }) + console.log("Current changeset is:", changeset); + await this.AddChange(csId, changeset) + } catch (e) { + console.error("Could not open/upload changeset due to ", e) + this.currentChangeset.setData("") + } } else { // There still exists an open changeset (or at least we hope so) const csId = this.currentChangeset.data; - self.AddChange( - csId, - generateChangeXML(csId), - allElements, - whenDone, - (e) => { - console.warn("Could not upload, changeset is probably closed: ", e); - // Mark the CS as closed... - this.currentChangeset.setData(""); - // ... and try again. As the cs is closed, no recursive loop can exist - self.UploadChangeset(layout, allElements, generateChangeXML, whenDone, onFail); - } - ) + try { + await this.AddChange( + csId, + generateChangeXML(csId)) + } catch (e) { + console.warn("Could not upload, changeset is probably closed: ", e); + // Mark the CS as closed... + this.currentChangeset.setData(""); + // ... and try again. As the cs is closed, no recursive loop can exist + await this.UploadChangeset(layout, generateChangeXML) + } } } @@ -143,6 +157,13 @@ export class ChangesetHandler { reason: string, allElements: ElementStorage, continuation: () => void) { + return this.DeleteElementAsync(object, layout, reason, allElements).then(continuation) + } + + public async DeleteElementAsync(object: OsmObject, + layout: LayoutConfig, + reason: string, + allElements: ElementStorage): Promise { function generateChangeXML(csId: string) { let [lat, lon] = object.centerpoint(); @@ -151,9 +172,7 @@ export class ChangesetHandler { changes += `<${object.type} id="${object.id}" version="${object.version}" changeset="${csId}" lat="${lat}" lon="${lon}" />`; changes += ""; - continuation() return changes; - } @@ -163,143 +182,122 @@ export class ChangesetHandler { return; } - const self = this; - this.OpenChangeset(layout, (csId: string) => { - - // The cs is open - let us actually upload! - const changes = generateChangeXML(csId) - - self.AddChange(csId, changes, allElements, (csId) => { - console.log("Successfully deleted ", object.id) - self.CloseChangeset(csId, continuation) - }, (csId) => { - alert("Deletion failed... Should not happend") - // FAILED - self.CloseChangeset(csId, continuation) - }) - }, { - isDeletionCS: true, - deletionReason: reason - } - ) + const csId = await this.OpenChangeset(layout, { + isDeletionCS: true, + deletionReason: reason + }) + // The cs is open - let us actually upload! + const changes = generateChangeXML(csId) + await this.AddChange(csId, changes) + await this.CloseChangeset(csId) } - private CloseChangeset(changesetId: string = undefined, continuation: (() => void) = () => { - }) { - if (changesetId === undefined) { - changesetId = this.currentChangeset.data; - } - if (changesetId === undefined) { - return; - } - console.log("closing changeset", changesetId); - this.currentChangeset.setData(""); - this.auth.xhr({ - method: 'PUT', - path: '/api/0.6/changeset/' + changesetId + '/close', - }, function (err, response) { - if (response == null) { - - console.log("err", err); + private async CloseChangeset(changesetId: string = undefined): Promise { + const self = this + return new Promise(function (resolve, reject) { + if (changesetId === undefined) { + changesetId = self.currentChangeset.data; } - console.log("Closed changeset ", changesetId) - - if (continuation !== undefined) { - continuation(); + if (changesetId === undefined) { + return; } - }); + console.log("closing changeset", changesetId); + self.currentChangeset.setData(""); + self.auth.xhr({ + method: 'PUT', + path: '/api/0.6/changeset/' + changesetId + '/close', + }, function (err, response) { + if (response == null) { + + console.log("err", err); + } + console.log("Closed changeset ", changesetId) + resolve() + }); + }) } private OpenChangeset( layout: LayoutConfig, - continuation: (changesetId: string) => void, options?: { isDeletionCS?: boolean, deletionReason?: string, - onFail?: () => void } - ) { - options = options ?? {} - options.isDeletionCS = options.isDeletionCS ?? false - const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; - let comment = `Adding data with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.isDeletionCS) { - comment = `Deleting a point with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.deletionReason) { - comment += ": " + options.deletionReason; - } - } - - let path = window.location.pathname; - path = path.substr(1, path.lastIndexOf("/")); - const metadata = [ - ["created_by", `MapComplete ${Constants.vNumber}`], - ["comment", comment], - ["deletion", options.isDeletionCS ? "yes" : undefined], - ["theme", layout.id], - ["language", Locale.language.data], - ["host", window.location.host], - ["path", path], - ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], - ["imagery", State.state.backgroundLayer.data.id], - ["theme-creator", layout.maintainer] - ] - .filter(kv => (kv[1] ?? "") !== "") - .map(kv => ``) - .join("\n") - - this.auth.xhr({ - method: 'PUT', - path: '/api/0.6/changeset/create', - options: {header: {'Content-Type': 'text/xml'}}, - content: [``, - metadata, - ``].join("") - }, function (err, response) { - if (response === undefined) { - console.log("err", err); - if (options.onFail) { - options.onFail() + ): Promise { + const self = this; + return new Promise(function (resolve, reject) { + options = options ?? {} + options.isDeletionCS = options.isDeletionCS ?? false + const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; + let comment = `Adding data with #MapComplete for theme #${layout.id}${commentExtra}` + if (options.isDeletionCS) { + comment = `Deleting a point with #MapComplete for theme #${layout.id}${commentExtra}` + if (options.deletionReason) { + comment += ": " + options.deletionReason; } - return; - } else { - continuation(response); } - }); + + let path = window.location.pathname; + path = path.substr(1, path.lastIndexOf("/")); + const metadata = [ + ["created_by", `MapComplete ${Constants.vNumber}`], + ["comment", comment], + ["deletion", options.isDeletionCS ? "yes" : undefined], + ["theme", layout.id], + ["language", Locale.language.data], + ["host", window.location.host], + ["path", path], + ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], + ["imagery", State.state.backgroundLayer.data.id], + ["theme-creator", layout.maintainer] + ] + .filter(kv => (kv[1] ?? "") !== "") + .map(kv => ``) + .join("\n") + + + self.auth.xhr({ + method: 'PUT', + path: '/api/0.6/changeset/create', + options: {header: {'Content-Type': 'text/xml'}}, + content: [``, + metadata, + ``].join("") + }, function (err, response) { + if (response === undefined) { + console.log("err", err); + reject(err) + } else { + resolve(response); + } + }); + }) + } /** * Upload a changesetXML - * @param changesetId - * @param changesetXML - * @param allElements - * @param continuation - * @param onFail - * @constructor - * @private */ private AddChange(changesetId: string, - changesetXML: string, - allElements: ElementStorage, - continuation: ((changesetId: string) => void), - onFail: ((changesetId: string, reason: string) => void) = undefined) { - this.auth.xhr({ - method: 'POST', - options: {header: {'Content-Type': 'text/xml'}}, - path: '/api/0.6/changeset/' + changesetId + '/upload', - content: changesetXML - }, function (err, response) { - if (response == null) { - console.log("err", err); - if (onFail) { - onFail(changesetId, err); + changesetXML: string): Promise { + const self = this; + return new Promise(function (resolve, reject) { + self.auth.xhr({ + method: 'POST', + options: {header: {'Content-Type': 'text/xml'}}, + path: '/api/0.6/changeset/' + changesetId + '/upload', + content: changesetXML + }, function (err, response) { + if (response == null) { + console.log("err", err); + reject(err); } - return; - } - ChangesetHandler.parseUploadChangesetResponse(response, allElements); - console.log("Uploaded changeset ", changesetId); - continuation(changesetId); - }); + self.parseUploadChangesetResponse(response); + console.log("Uploaded changeset ", changesetId); + resolve(changesetId); + }); + }) + } diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 01d18f8cd..4e1a9297a 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -9,6 +9,7 @@ import Img from "../../UI/Base/Img"; import {Utils} from "../../Utils"; import {OsmObject} from "./OsmObject"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {Changes} from "./Changes"; export default class UserDetails { @@ -54,31 +55,33 @@ export class OsmConnection { private _onLoggedIn: ((userDetails: UserDetails) => void)[] = []; private readonly _iframeMode: Boolean | boolean; private readonly _singlePage: boolean; - private readonly _oauth_config: { + public readonly _oauth_config: { oauth_consumer_key: string, oauth_secret: string, url: string }; private isChecking = false; - constructor(dryRun: boolean, - fakeUser: boolean, - oauth_token: UIEventSource, + constructor(options:{dryRun?: false | boolean, + fakeUser?: false | boolean, + allElements: ElementStorage, + changes: Changes, + oauth_token?: UIEventSource, // Used to keep multiple changesets open and to write to the correct changeset layoutName: string, - singlePage: boolean = true, - osmConfiguration: "osm" | "osm-test" = 'osm' + singlePage?: boolean, + osmConfiguration?: "osm" | "osm-test" } ) { - this.fakeUser = fakeUser; - this._singlePage = singlePage; - this._oauth_config = OsmConnection.oauth_configs[osmConfiguration] ?? OsmConnection.oauth_configs.osm; + this.fakeUser = options.fakeUser ?? false; + this._singlePage = options.singlePage ?? true; + this._oauth_config = OsmConnection.oauth_configs[options.osmConfiguration ?? 'osm'] ?? OsmConnection.oauth_configs.osm; console.debug("Using backend", this._oauth_config.url) OsmObject.SetBackendUrl(this._oauth_config.url + "/") this._iframeMode = Utils.runningFromConsole ? false : window !== window.top; this.userDetails = new UIEventSource(new UserDetails(this._oauth_config.url), "userDetails"); - this.userDetails.data.dryRun = dryRun || fakeUser; - if (fakeUser) { + this.userDetails.data.dryRun = (options.dryRun ?? false) || (options.fakeUser ?? false) ; + if (options.fakeUser) { const ud = this.userDetails.data; ud.csCount = 5678 ud.loggedIn = true; @@ -94,23 +97,24 @@ export class OsmConnection { self.AttemptLogin() } }); - this._dryRun = dryRun; + this.isLoggedIn.addCallbackAndRunD(li => console.log("User is logged in!", li)) + this._dryRun = options.dryRun; this.updateAuthObject(); this.preferencesHandler = new OsmPreferences(this.auth, this); - this.changesetHandler = new ChangesetHandler(layoutName, dryRun, this, this.auth); - if (oauth_token.data !== undefined) { - console.log(oauth_token.data) + this.changesetHandler = new ChangesetHandler(options.layoutName, options.dryRun, this, options.allElements, options.changes, this.auth); + if (options.oauth_token?.data !== undefined) { + console.log(options.oauth_token.data) const self = this; - this.auth.bootstrapToken(oauth_token.data, + this.auth.bootstrapToken(options.oauth_token.data, (x) => { console.log("Called back: ", x) self.AttemptLogin(); }, this.auth); - oauth_token.setData(undefined); + options. oauth_token.setData(undefined); } if (this.auth.authenticated()) { @@ -123,10 +127,8 @@ export class OsmConnection { public UploadChangeset( layout: LayoutConfig, allElements: ElementStorage, - generateChangeXML: (csid: string) => string, - whenDone: (csId: string) => void, - onFail: () => {}) { - this.changesetHandler.UploadChangeset(layout, allElements, generateChangeXML, whenDone, onFail); + generateChangeXML: (csid: string) => string): Promise { + return this.changesetHandler.UploadChangeset(layout, generateChangeXML); } public GetPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource { diff --git a/Logic/Osm/OsmObject.ts b/Logic/Osm/OsmObject.ts index 8027a18d9..4538622d1 100644 --- a/Logic/Osm/OsmObject.ts +++ b/Logic/Osm/OsmObject.ts @@ -1,7 +1,7 @@ import {Utils} from "../../Utils"; import * as polygon_features from "../../assets/polygon-features.json"; import {UIEventSource} from "../UIEventSource"; -import {BBox} from "../GeoOperations"; +import {BBox} from "../BBox"; export abstract class OsmObject { @@ -157,23 +157,6 @@ export abstract class OsmObject { const elements: any[] = data.elements; return OsmObject.ParseObjects(elements); } - - public static DownloadAll(neededIds, forceRefresh = true): UIEventSource { - // local function which downloads all the objects one by one - // this is one big loop, running one download, then rerunning the entire function - - const allSources: UIEventSource [] = neededIds.map(id => OsmObject.DownloadObject(id, forceRefresh)) - const allCompleted = new UIEventSource(undefined).map(_ => { - return !allSources.some(uiEventSource => uiEventSource.data === undefined) - }, allSources) - return allCompleted.map(completed => { - if (completed) { - return allSources.map(src => src.data) - } - return undefined - }); - } - protected static isPolygon(tags: any): boolean { for (const tagsKey in tags) { if (!tags.hasOwnProperty(tagsKey)) { diff --git a/Logic/Osm/Overpass.ts b/Logic/Osm/Overpass.ts index de6b65287..47b92e278 100644 --- a/Logic/Osm/Overpass.ts +++ b/Logic/Osm/Overpass.ts @@ -1,9 +1,9 @@ import * as OsmToGeoJson from "osmtogeojson"; -import Bounds from "../../Models/Bounds"; import {TagsFilter} from "../Tags/TagsFilter"; import RelationsTracker from "./RelationsTracker"; import {Utils} from "../../Utils"; import {UIEventSource} from "../UIEventSource"; +import {BBox} from "../BBox"; /** * Interfaces overpass to get all the latest data @@ -11,15 +11,15 @@ import {UIEventSource} from "../UIEventSource"; export class Overpass { public static testUrl: string = null private _filter: TagsFilter - private readonly _interpreterUrl: UIEventSource; + private readonly _interpreterUrl: string; private readonly _timeout: UIEventSource; private readonly _extraScripts: string[]; private _includeMeta: boolean; private _relationTracker: RelationsTracker; - - + + constructor(filter: TagsFilter, extraScripts: string[], - interpreterUrl: UIEventSource, + interpreterUrl: string, timeout: UIEventSource, relationTracker: RelationsTracker, includeMeta = true) { @@ -31,9 +31,9 @@ export class Overpass { this._relationTracker = relationTracker } - public async queryGeoJson(bounds: Bounds): Promise<[any, Date]> { + public async queryGeoJson(bounds: BBox): Promise<[any, Date]> { - let query = this.buildQuery("[bbox:" + bounds.south + "," + bounds.west + "," + bounds.north + "," + bounds.east + "]") + let query = this.buildQuery("[bbox:" + bounds.getSouth() + "," + bounds.getWest() + "," + bounds.getNorth() + "," + bounds.getEast() + "]") if (Overpass.testUrl !== null) { console.log("Using testing URL") @@ -41,10 +41,13 @@ export class Overpass { } const self = this; const json = await Utils.downloadJson(query) - - if (json.elements === [] && ((json.remarks ?? json.remark).indexOf("runtime error") >= 0)) { - console.log("Timeout or other runtime error"); - throw("Runtime error (timeout)") + console.log("Got json!", json) + if (json.elements.length === 0 && json.remark !== undefined) { + console.warn("Timeout or other runtime error while querying overpass", json.remark); + throw `Runtime error (timeout or similar)${json.remark}` + } + if(json.elements.length === 0){ + console.warn("No features for" ,json) } self._relationTracker.RegisterRelations(json) @@ -65,6 +68,6 @@ export class Overpass { } const query = `[out:json][timeout:${this._timeout.data}]${bbox};(${filter});out body;${this._includeMeta ? 'out meta;' : ''}>;out skel qt;` - return `${this._interpreterUrl.data}?data=${encodeURIComponent(query)}` + return `${this._interpreterUrl}?data=${encodeURIComponent(query)}` } } diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 6e8f3e0fc..360bb54e5 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -31,7 +31,7 @@ export default class SimpleMetaTagger { "_version_number"], doc: "Information about the last edit of this object." }, - (feature) => {/*Note: also handled by 'UpdateTagsFromOsmAPI'*/ + (feature) => {/*Note: also called by 'UpdateTagsFromOsmAPI'*/ const tgs = feature.properties; @@ -48,6 +48,7 @@ export default class SimpleMetaTagger { move("changeset", "_last_edit:changeset") move("timestamp", "_last_edit:timestamp") move("version", "_version_number") + return true; } ) private static latlon = new SimpleMetaTagger({ @@ -62,6 +63,7 @@ export default class SimpleMetaTagger { feature.properties["_lon"] = "" + lon; feature._lon = lon; // This is dirty, I know feature._lat = lat; + return true; }) ); private static surfaceArea = new SimpleMetaTagger( @@ -74,6 +76,7 @@ export default class SimpleMetaTagger { feature.properties["_surface"] = "" + sqMeters; feature.properties["_surface:ha"] = "" + Math.floor(sqMeters / 1000) / 10; feature.area = sqMeters; + return true; }) ); @@ -84,7 +87,7 @@ export default class SimpleMetaTagger { }, (feature => { - const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.data?.layers?.map(layer => layer.units ?? []))); + const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.layers?.map(layer => layer.units ?? []))); if (units.length == 0) { return; } @@ -94,6 +97,9 @@ export default class SimpleMetaTagger { continue; } for (const unit of units) { + if (unit === undefined) { + continue + } if (unit.appliesToKeys === undefined) { console.error("The unit ", unit, "has no appliesToKey defined") continue @@ -102,7 +108,12 @@ export default class SimpleMetaTagger { continue; } const value = feature.properties[key] - const [, denomination] = unit.findDenomination(value) + const denom = unit.findDenomination(value) + if (denom === undefined) { + // no valid value found + break; + } + const [, denomination] = denom; let canonical = denomination?.canonicalValue(value) ?? undefined; if (canonical === value) { break; @@ -118,9 +129,7 @@ export default class SimpleMetaTagger { } } - if (rewritten) { - State.state.allElements.getEventSourceById(feature.id).ping(); - } + return rewritten }) ) @@ -135,6 +144,7 @@ export default class SimpleMetaTagger { const km = Math.floor(l / 1000) const kmRest = Math.round((l - km * 1000) / 100) feature.properties["_length:km"] = "" + km + "." + kmRest + return true; }) ) private static country = new SimpleMetaTagger( @@ -144,7 +154,6 @@ export default class SimpleMetaTagger { }, feature => { - let centerPoint: any = GeoOperations.centerpoint(feature); const lat = centerPoint.geometry.coordinates[1]; const lon = centerPoint.geometry.coordinates[0]; @@ -157,11 +166,11 @@ export default class SimpleMetaTagger { const tagsSource = State.state.allElements.getEventSourceById(feature.properties.id); tagsSource.ping(); } - } catch (e) { console.warn(e) } }) + return false; } ) private static isOpen = new SimpleMetaTagger( @@ -174,7 +183,7 @@ export default class SimpleMetaTagger { if (Utils.runningFromConsole) { // We are running from console, thus probably creating a cache // isOpen is irrelevant - return + return false } const tagsSource = State.state.allElements.getEventSourceById(feature.properties.id); @@ -199,7 +208,7 @@ export default class SimpleMetaTagger { if (oldNextChange > (new Date()).getTime() && tags["_isOpen:oldvalue"] === tags["opening_hours"]) { // Already calculated and should not yet be triggered - return; + return false; } tags["_isOpen"] = oh.getState() ? "yes" : "no"; @@ -227,6 +236,7 @@ export default class SimpleMetaTagger { } } updateTags(); + return true; } catch (e) { console.warn("Error while parsing opening hours of ", tags.id, e); tags["_isOpen"] = "parse_error"; @@ -244,11 +254,11 @@ export default class SimpleMetaTagger { const tags = feature.properties; const direction = tags["camera:direction"] ?? tags["direction"]; if (direction === undefined) { - return; + return false; } const n = cardinalDirections[direction] ?? Number(direction); if (isNaN(n)) { - return; + return false; } // The % operator has range (-360, 360). We apply a trick to get [0, 360). @@ -256,126 +266,17 @@ export default class SimpleMetaTagger { tags["_direction:numerical"] = normalized; tags["_direction:leftright"] = normalized <= 180 ? "right" : "left"; - + return true; }) ) - private static carriageWayWidth = new SimpleMetaTagger( - { - keys: ["_width:needed", "_width:needed:no_pedestrians", "_width:difference"], - doc: "Legacy for a specific project calculating the needed width for safe traffic on a road. Only activated if 'width:carriageway' is present" - }, - feature => { - const properties = feature.properties; - if (properties["width:carriageway"] === undefined) { - return; - } - - const carWidth = 2; - const cyclistWidth = 1.5; - const pedestrianWidth = 0.75; - - - const _leftSideParking = - new And([new Tag("parking:lane:left", "parallel"), new Tag("parking:lane:right", "no_parking")]); - const _rightSideParking = - new And([new Tag("parking:lane:right", "parallel"), new Tag("parking:lane:left", "no_parking")]); - - const _bothSideParking = new Tag("parking:lane:both", "parallel"); - const _noSideParking = new Tag("parking:lane:both", "no_parking"); - const _otherParkingMode = - new Or([ - new Tag("parking:lane:both", "perpendicular"), - new Tag("parking:lane:left", "perpendicular"), - new Tag("parking:lane:right", "perpendicular"), - new Tag("parking:lane:both", "diagonal"), - new Tag("parking:lane:left", "diagonal"), - new Tag("parking:lane:right", "diagonal"), - ]) - - const _sidewalkBoth = new Tag("sidewalk", "both"); - const _sidewalkLeft = new Tag("sidewalk", "left"); - const _sidewalkRight = new Tag("sidewalk", "right"); - const _sidewalkNone = new Tag("sidewalk", "none"); - - - let parallelParkingCount = 0; - - - const _oneSideParking = new Or([_leftSideParking, _rightSideParking]); - - if (_oneSideParking.matchesProperties(properties)) { - parallelParkingCount = 1; - } else if (_bothSideParking.matchesProperties(properties)) { - parallelParkingCount = 2; - } else if (_noSideParking.matchesProperties(properties)) { - parallelParkingCount = 0; - } else if (_otherParkingMode.matchesProperties(properties)) { - parallelParkingCount = 0; - } else { - console.log("No parking data for ", properties.name, properties.id) - } - - - let pedestrianFlowNeeded; - if (_sidewalkBoth.matchesProperties(properties)) { - pedestrianFlowNeeded = 0; - } else if (_sidewalkNone.matchesProperties(properties)) { - pedestrianFlowNeeded = 2; - } else if (_sidewalkLeft.matchesProperties(properties) || _sidewalkRight.matchesProperties(properties)) { - pedestrianFlowNeeded = 1; - } else { - pedestrianFlowNeeded = -1; - } - - - let onewayCar = properties.oneway === "yes"; - let onewayBike = properties["oneway:bicycle"] === "yes" || - (onewayCar && properties["oneway:bicycle"] === undefined) - - let cyclingAllowed = - !(properties.bicycle === "use_sidepath" - || properties.bicycle === "no"); - - let carWidthUsed = (onewayCar ? 1 : 2) * carWidth; - properties["_width:needed:cars"] = Utils.Round(carWidthUsed); - properties["_width:needed:parking"] = Utils.Round(parallelParkingCount * carWidth) - - - let cyclistWidthUsed = 0; - if (cyclingAllowed) { - cyclistWidthUsed = (onewayBike ? 1 : 2) * cyclistWidth; - } - properties["_width:needed:cyclists"] = Utils.Round(cyclistWidthUsed) - - - const width = parseFloat(properties["width:carriageway"]); - - - const targetWidthIgnoringPedestrians = - carWidthUsed + - cyclistWidthUsed + - parallelParkingCount * carWidthUsed; - properties["_width:needed:no_pedestrians"] = Utils.Round(targetWidthIgnoringPedestrians); - - const pedestriansNeed = Math.max(0, pedestrianFlowNeeded) * pedestrianWidth; - const targetWidth = targetWidthIgnoringPedestrians + pedestriansNeed; - properties["_width:needed"] = Utils.Round(targetWidth); - properties["_width:needed:pedestrians"] = Utils.Round(pedestriansNeed) - - - properties["_width:difference"] = Utils.Round(targetWidth - width); - properties["_width:difference:no_pedestrians"] = Utils.Round(targetWidthIgnoringPedestrians - width); - - } - ); private static currentTime = new SimpleMetaTagger( { keys: ["_now:date", "_now:datetime", "_loaded:date", "_loaded:_datetime"], doc: "Adds the time that the data got loaded - pretty much the time of downloading from overpass. The format is YYYY-MM-DD hh:mm, aka 'sortable' aka ISO-8601-but-not-entirely", includesDates: true }, - (feature, _, freshness) => { + (feature, freshness) => { const now = new Date(); if (typeof freshness === "string") { @@ -394,7 +295,7 @@ export default class SimpleMetaTagger { feature.properties["_now:datetime"] = datetime(now); feature.properties["_loaded:date"] = date(freshness); feature.properties["_loaded:datetime"] = datetime(freshness); - + return true; } ) public static metatags = [ @@ -404,7 +305,6 @@ export default class SimpleMetaTagger { SimpleMetaTagger.canonicalize, SimpleMetaTagger.country, SimpleMetaTagger.isOpen, - SimpleMetaTagger.carriageWayWidth, SimpleMetaTagger.directionSimplified, SimpleMetaTagger.currentTime, SimpleMetaTagger.objectMetaInfo @@ -413,12 +313,18 @@ export default class SimpleMetaTagger { public readonly keys: string[]; public readonly doc: string; public readonly includesDates: boolean - private readonly _f: (feature: any, index: number, freshness: Date) => void; + public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date) => boolean; - constructor(docs: { keys: string[], doc: string, includesDates?: boolean }, f: ((feature: any, index: number, freshness: Date) => void)) { + /*** + * A function that adds some extra data to a feature + * @param docs: what does this extra data do? + * @param f: apply the changes. Returns true if something changed + */ + constructor(docs: { keys: string[], doc: string, includesDates?: boolean }, + f: ((feature: any, freshness: Date) => boolean)) { this.keys = docs.keys; this.doc = docs.doc; - this._f = f; + this.applyMetaTagsOnFeature = f; this.includesDates = docs.includesDates ?? false; for (const key of docs.keys) { if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) { @@ -450,12 +356,4 @@ export default class SimpleMetaTagger { return new Combine(subElements).SetClass("flex-col") } - public addMetaTags(features: { feature: any, freshness: Date }[]) { - for (let i = 0; i < features.length; i++) { - let feature = features[i]; - this._f(feature.feature, i, feature.freshness); - } - } - - } diff --git a/Logic/Tags/RegexTag.ts b/Logic/Tags/RegexTag.ts index 20fbbbcbf..fae2fd70b 100644 --- a/Logic/Tags/RegexTag.ts +++ b/Logic/Tags/RegexTag.ts @@ -19,6 +19,9 @@ export class RegexTag extends TagsFilter { if (fromTag === undefined) { return; } + if(typeof fromTag === "number"){ + fromTag = "" + fromTag; + } if (typeof possibleRegex === "string") { return fromTag === possibleRegex; } diff --git a/Logic/UIEventSource.ts b/Logic/UIEventSource.ts index 42282ea2a..5f51dc004 100644 --- a/Logic/UIEventSource.ts +++ b/Logic/UIEventSource.ts @@ -64,7 +64,7 @@ export class UIEventSource { public static FromPromise(promise : Promise): UIEventSource{ const src = new UIEventSource(undefined) - promise.then(d => src.setData(d)) + promise?.then(d => src.setData(d)) return src } diff --git a/Models/Bounds.ts b/Models/Bounds.ts deleted file mode 100644 index 3a993c8e0..000000000 --- a/Models/Bounds.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface Bounds { - north: number, - east: number, - south: number, - west: number -} \ No newline at end of file diff --git a/Models/Constants.ts b/Models/Constants.ts index b3f31280e..855f9dd2b 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,23 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-alpha-0"; + public static vNumber = "0.10.0-rc2"; + public static ImgurApiKey = '7070e7167f0a25a' + public static readonly mapillary_client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' + public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" + + public static defaultOverpassUrls = [ + // The official instance, 10000 queries per day per project allowed + "https://overpass-api.de/api/interpreter", + // 'Fair usage' + "https://overpass.kumi.systems/api/interpreter", + // "https://overpass.nchc.org.tw/api/interpreter", + "https://overpass.openstreetmap.ru/cgi/interpreter", + // The french api, only 1000 per day per project allowed, so we put it as last resort + "https://overpass.openstreetmap.fr/api/interpreter" + ] + + // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/Models/FilteredLayer.ts b/Models/FilteredLayer.ts index 6c387270f..68ffb4483 100644 --- a/Models/FilteredLayer.ts +++ b/Models/FilteredLayer.ts @@ -1,9 +1,10 @@ import {UIEventSource} from "../Logic/UIEventSource"; import LayerConfig from "./ThemeConfig/LayerConfig"; import {And} from "../Logic/Tags/And"; +import FilterConfig from "./ThemeConfig/FilterConfig"; export default interface FilteredLayer { readonly isDisplayed: UIEventSource; - readonly appliedFilters: UIEventSource; + readonly appliedFilters: UIEventSource<{filter: FilterConfig, selected: number}[]>; readonly layerDef: LayerConfig; } \ No newline at end of file diff --git a/Models/ThemeConfig/FilterConfig.ts b/Models/ThemeConfig/FilterConfig.ts index 464919d76..7a032c6de 100644 --- a/Models/ThemeConfig/FilterConfig.ts +++ b/Models/ThemeConfig/FilterConfig.ts @@ -5,7 +5,8 @@ import Translations from "../../UI/i18n/Translations"; import {TagUtils} from "../../Logic/Tags/TagUtils"; export default class FilterConfig { - readonly options: { + public readonly id: string + public readonly options: { question: Translation; osmTags: TagsFilter; }[]; @@ -14,11 +15,18 @@ export default class FilterConfig { if (json.options === undefined) { throw `A filter without options was given at ${context}` } + if (json.id === undefined) { + throw `A filter without id was found at ${context}` + } + if(json.id.match(/^[a-zA-Z0-9_-]*$/) === null){ + throw `A filter with invalid id was found at ${context}. Ids should only contain letters, numbers or - _` + + } if (json.options.map === undefined) { throw `A filter was given where the options aren't a list at ${context}` } - + this.id = json.id; this.options = json.options.map((option, i) => { const question = Translations.T( option.question, @@ -34,5 +42,9 @@ export default class FilterConfig { return {question: question, osmTags: osmTags}; }); + + if(this.options.length > 1 && this.options[0].osmTags["and"]?.length !== 0){ + throw "Error in "+context+"."+this.id+": the first option of a multi-filter should always be the 'reset' option and not have any filters" + } } } \ No newline at end of file diff --git a/Models/ThemeConfig/Json/FilterConfigJson.ts b/Models/ThemeConfig/Json/FilterConfigJson.ts index c49f9f3eb..7151e3854 100644 --- a/Models/ThemeConfig/Json/FilterConfigJson.ts +++ b/Models/ThemeConfig/Json/FilterConfigJson.ts @@ -1,6 +1,10 @@ import {AndOrTagConfigJson} from "./TagConfigJson"; export default interface FilterConfigJson { + /** + * An id/name for this filter, used to set the URL parameters + */ + id: string, /** * The options for a filter * If there are multiple options these will be a list of radio buttons diff --git a/Models/ThemeConfig/Json/LayoutConfigJson.ts b/Models/ThemeConfig/Json/LayoutConfigJson.ts index 856ab2736..73caee792 100644 --- a/Models/ThemeConfig/Json/LayoutConfigJson.ts +++ b/Models/ThemeConfig/Json/LayoutConfigJson.ts @@ -228,8 +228,8 @@ export interface LayoutConfigJson { */ maxZoom?: number, /** - * The number of elements that should be showed (in total) before clustering starts to happen. - * If clustering is defined, defaults to 0 + * The number of elements per tile needed to start clustering + * If clustering is defined, defaults to 25 */ minNeededElements?: number }, @@ -263,9 +263,9 @@ export interface LayoutConfigJson { enablePdfDownload?: boolean; /** - * Set a different overpass URL. Default: https://overpass-api.de/api/interpreter + * Set one or more overpass URLs to use for this theme.. */ - overpassUrl?: string; + overpassUrl?: string | string[]; /** * Set a different timeout for overpass queries - in seconds. Default: 30s */ diff --git a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts index 415c17cd1..0965a24b6 100644 --- a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts @@ -5,6 +5,13 @@ import {AndOrTagConfigJson} from "./TagConfigJson"; * If the desired tags are missing and a question is defined, a question will be shown instead. */ export interface TagRenderingConfigJson { + + /** + * The id of the tagrendering, should be an unique string. + * Used to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise + */ + id?: string, + /** * Renders this value. Note that "{key}"-parts are substituted by the corresponding values of the element. * If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value. diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index c3cadc1e0..1e8fae148 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -18,6 +18,7 @@ import FilterConfig from "./FilterConfig"; import {Unit} from "../Unit"; import DeleteConfig from "./DeleteConfig"; import Svg from "../../Svg"; +import Img from "../../UI/Base/Img"; export default class LayerConfig { static WAYHANDLING_DEFAULT = 0; @@ -154,6 +155,9 @@ export default class LayerConfig { this.minzoom = json.minzoom ?? 0; this.minzoomVisible = json.minzoomVisible ?? this.minzoom; this.wayHandling = json.wayHandling ?? 0; + if(json.presets !== undefined && json.presets?.map === undefined){ + throw "Presets should be a list of items (at "+context+")" + } this.presets = (json.presets ?? []).map((pr, i) => { let preciseInput = undefined; @@ -287,7 +291,14 @@ export default class LayerConfig { } this.tagRenderings = trs(json.tagRenderings, false); + + const missingIds = json.tagRenderings?.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined) ?? []; + if(missingIds.length > 0 && official){ + console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds) + throw "Missing ids in tagrenderings" + } + this.filters = (json.filter ?? []).map((option, i) => { return new FilterConfig(option, `${context}.filter-[${i}]`) }); @@ -499,12 +510,13 @@ export default class LayerConfig { ); const match = sourcePart.match(/([a-zA-Z0-9_]*):([^;]*)/); if (match !== null && Svg.All[match[1] + ".svg"] !== undefined) { - html = new Combine([ + html = new Img( (Svg.All[match[1] + ".svg"] as string).replace( /#000000/g, match[2] ), - ]).SetStyle(style); + true + ).SetStyle(style); } return html; } diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index dd0d472ed..4f8551632 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -5,8 +5,8 @@ import SharedTagRenderings from "../../Customizations/SharedTagRenderings"; import AllKnownLayers from "../../Customizations/AllKnownLayers"; import {Utils} from "../../Utils"; import LayerConfig from "./LayerConfig"; -import {Unit} from "../Unit"; import {LayerConfigJson} from "./Json/LayerConfigJson"; +import Constants from "../Constants"; export default class LayoutConfig { public readonly id: string; @@ -51,7 +51,7 @@ export default class LayoutConfig { How long is the cache valid, in seconds? */ public readonly cacheTimeout?: number; - public readonly overpassUrl: string; + public readonly overpassUrl: string[]; public readonly overpassTimeout: number; public readonly official: boolean; @@ -87,6 +87,9 @@ export default class LayoutConfig { this.startZoom = json.startZoom; this.startLat = json.startLat; this.startLon = json.startLon; + if(json.widenFactor < 1){ + throw "Widenfactor too small" + } this.widenFactor = json.widenFactor ?? 1.5; this.roamingRenderings = (json.roamingRenderings ?? []).map((tr, i) => { if (typeof tr === "string") { @@ -127,17 +130,12 @@ export default class LayoutConfig { this.clustering = { maxZoom: 16, - minNeededElements: 500 + minNeededElements: 25 }; if (json.clustering) { this.clustering = { maxZoom: json.clustering.maxZoom ?? 18, - minNeededElements: json.clustering.minNeededElements ?? 1 - } - for (const layer of this.layers) { - if (layer.wayHandling !== LayerConfig.WAYHANDLING_CENTER_ONLY) { - console.debug("WARNING: In order to allow clustering, every layer must be set to CENTER_ONLY. Layer", layer.id, "does not respect this for layout", this.id); - } + minNeededElements: json.clustering.minNeededElements ?? 25 } } @@ -160,7 +158,14 @@ export default class LayoutConfig { this.enablePdfDownload = json.enablePdfDownload ?? false; this.customCss = json.customCss; this.cacheTimeout = json.cacheTimout ?? (60 * 24 * 60 * 60) - this.overpassUrl = json.overpassUrl ?? "https://overpass-api.de/api/interpreter" + this.overpassUrl = Constants.defaultOverpassUrls + if(json.overpassUrl !== undefined){ + if(typeof json.overpassUrl === "string"){ + this.overpassUrl = [json.overpassUrl] + }else{ + this.overpassUrl = json.overpassUrl + } + } this.overpassTimeout = json.overpassTimeout ?? 30 } diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index 912152c2e..4edd0da1d 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -13,6 +13,7 @@ import {Utils} from "../../Utils"; */ export default class TagRenderingConfig { + readonly id: string; readonly render?: Translation; readonly question?: Translation; readonly condition?: TagsFilter; @@ -56,6 +57,8 @@ export default class TagRenderingConfig { return; } + + this.id = json.id ?? ""; this.render = Translations.T(json.render, context + ".render"); this.question = Translations.T(json.question, context + ".question"); this.roaming = json.roaming ?? false; diff --git a/Models/TileRange.ts b/Models/TileRange.ts index e1dba5532..da30e498c 100644 --- a/Models/TileRange.ts +++ b/Models/TileRange.ts @@ -5,4 +5,107 @@ export interface TileRange { yend: number, total: number, zoomlevel: number +} + +export class Tiles { + + public static MapRange(tileRange: TileRange, f: (x: number, y: number) => T): T[] { + const result: T[] = [] + for (let x = tileRange.xstart; x <= tileRange.xend; x++) { + for (let y = tileRange.ystart; y <= tileRange.yend; y++) { + const t = f(x, y); + result.push(t) + } + } + return result; + } + + + private static tile2long(x, z) { + return (x / Math.pow(2, z) * 360 - 180); + } + + private static tile2lat(y, z) { + const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z); + return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); + } + + private static lon2tile(lon, zoom) { + return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom))); + } + + private static lat2tile(lat, zoom) { + return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom))); + } + + /** + * Calculates the tile bounds of the + * @param z + * @param x + * @param y + * @returns [[maxlat, minlon], [minlat, maxlon]] + */ + static tile_bounds(z: number, x: number, y: number): [[number, number], [number, number]] { + return [[Tiles.tile2lat(y, z), Tiles.tile2long(x, z)], [Tiles.tile2lat(y + 1, z), Tiles.tile2long(x + 1, z)]] + } + + + static tile_bounds_lon_lat(z: number, x: number, y: number): [[number, number], [number, number]] { + return [[Tiles.tile2long(x, z), Tiles.tile2lat(y, z)], [Tiles.tile2long(x + 1, z), Tiles.tile2lat(y + 1, z)]] + } + + /** + * Returns the centerpoint [lon, lat] of the specified tile + * @param z + * @param x + * @param y + */ + static centerPointOf(z: number, x: number, y: number): [number, number]{ + return [(Tiles.tile2long(x, z) + Tiles.tile2long(x+1, z)) / 2, (Tiles.tile2lat(y, z) + Tiles.tile2lat(y+1, z)) / 2] + } + + static tile_index(z: number, x: number, y: number): number { + return ((x * (2 << z)) + y) * 100 + z + } + /** + * Given a tile index number, returns [z, x, y] + * @param index + * @returns 'zxy' + */ + static tile_from_index(index: number): [number, number, number] { + const z = index % 100; + const factor = 2 << z + index = Math.floor(index / 100) + const x = Math.floor(index / factor) + return [z, x, index % factor] + } + + /** + * Return x, y of the tile containing (lat, lon) on the given zoom level + */ + static embedded_tile(lat: number, lon: number, z: number): { x: number, y: number, z: number } { + return {x: Tiles.lon2tile(lon, z), y: Tiles.lat2tile(lat, z), z: z} + } + + static TileRangeBetween(zoomlevel: number, lat0: number, lon0: number, lat1: number, lon1: number): TileRange { + const t0 = Tiles.embedded_tile(lat0, lon0, zoomlevel) + const t1 = Tiles.embedded_tile(lat1, lon1, zoomlevel) + + const xstart = Math.min(t0.x, t1.x) + const xend = Math.max(t0.x, t1.x) + const ystart = Math.min(t0.y, t1.y) + const yend = Math.max(t0.y, t1.y) + const total = (1 + xend - xstart) * (1 + yend - ystart) + + return { + xstart: xstart, + xend: xend, + ystart: ystart, + yend: yend, + total: total, + zoomlevel: zoomlevel + } + } + + } \ No newline at end of file diff --git a/State.ts b/State.ts index 105e7ef05..7279136b3 100644 --- a/State.ts +++ b/State.ts @@ -17,7 +17,7 @@ import FeaturePipeline from "./Logic/FeatureSource/FeaturePipeline"; import FilteredLayer from "./Models/FilteredLayer"; import ChangeToElementsActor from "./Logic/Actors/ChangeToElementsActor"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; -import {BBox} from "./Logic/GeoOperations"; +import {BBox} from "./Logic/BBox"; /** * Contains the global state: a bunch of UI-event sources @@ -27,16 +27,16 @@ export default class State { // The singleton of the global state public static state: State; - public readonly layoutToUse = new UIEventSource(undefined, "layoutToUse"); + public readonly layoutToUse : LayoutConfig; /** The mapping from id -> UIEventSource */ - public allElements: ElementStorage; + public allElements: ElementStorage = new ElementStorage(); /** THe change handler */ - public changes: Changes; + public changes: Changes = new Changes(); /** The leaflet instance of the big basemap */ @@ -81,9 +81,11 @@ export default class State { public readonly featureSwitchEnableExport: UIEventSource; public readonly featureSwitchFakeUser: UIEventSource; public readonly featureSwitchExportAsPdf: UIEventSource; - public readonly overpassUrl: UIEventSource; + public readonly overpassUrl: UIEventSource; public readonly overpassTimeout: UIEventSource; - public readonly overpassMaxZoom: UIEventSource = new UIEventSource(undefined); + + + public readonly overpassMaxZoom: UIEventSource = new UIEventSource(17, "overpass-max-zoom: point to switch between OSM-api and overpass"); public featurePipeline: FeaturePipeline; @@ -97,7 +99,7 @@ export default class State { * The current visible extent of the screen */ public readonly currentBounds = new UIEventSource(undefined) - + public backgroundLayer; public readonly backgroundLayerId: UIEventSource; @@ -155,8 +157,7 @@ export default class State { constructor(layoutToUse: LayoutConfig) { const self = this; - - this.layoutToUse.setData(layoutToUse); + this.layoutToUse = layoutToUse; // -- Location control initialization { @@ -193,14 +194,7 @@ export default class State { lat.setData(latlonz.lat); lon.setData(latlonz.lon); }); - - this.layoutToUse.addCallback((layoutToUse) => { - const lcd = self.locationControl.data; - lcd.zoom = lcd.zoom ?? layoutToUse?.startZoom; - lcd.lat = lcd.lat ?? layoutToUse?.startLat; - lcd.lon = lcd.lon ?? layoutToUse?.startLon; - self.locationControl.ping(); - }); + } // Helper function to initialize feature switches @@ -209,28 +203,19 @@ export default class State { deflt: (layout: LayoutConfig) => boolean, documentation: string ): UIEventSource { - const queryParameterSource = QueryParameters.GetQueryParameter( + + const defaultValue = deflt(self.layoutToUse); + const queryParam = QueryParameters.GetQueryParameter( key, - undefined, + "" + defaultValue, documentation ); - // I'm so sorry about someone trying to decipher this // It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened - return UIEventSource.flatten( - self.layoutToUse.map((layout) => { - const defaultValue = deflt(layout); - const queryParam = QueryParameters.GetQueryParameter( - key, - "" + defaultValue, - documentation - ); - return queryParam.map((str) => - str === undefined ? defaultValue : str !== "false" - ); - }), - [queryParameterSource] - ); + return queryParam.map((str) => + str === undefined ? defaultValue : str !== "false" + ) + } // Feature switch initialization - not as a function as the UIEventSources are readonly @@ -336,9 +321,9 @@ export default class State { ); this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl", - layoutToUse?.overpassUrl, + (layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(",") , "Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter" - ) + ).map(param => param.split(","), [], urls => urls.join(",")) this.overpassTimeout = QueryParameters.GetQueryParameter("overpassTimeout", "" + layoutToUse?.overpassTimeout, @@ -373,22 +358,20 @@ export default class State { return; } - this.osmConnection = new OsmConnection( - this.featureSwitchIsTesting.data, - this.featureSwitchFakeUser.data, - QueryParameters.GetQueryParameter( + this.osmConnection = new OsmConnection({ + changes: this.changes, + dryRun: this.featureSwitchIsTesting.data, + fakeUser: this.featureSwitchFakeUser.data, + allElements: this.allElements, + oauth_token: QueryParameters.GetQueryParameter( "oauth_token", undefined, "Used to complete the login" ), - layoutToUse?.id, - true, - // @ts-ignore - this.featureSwitchApiURL.data - ); + layoutName: layoutToUse?.id, + osmConfiguration: <'osm' | 'osm-test'>this.featureSwitchApiURL.data + }) - this.allElements = new ElementStorage(); - this.changes = new Changes(); new ChangeToElementsActor(this.changes, this.allElements) @@ -415,11 +398,11 @@ export default class State { Locale.language .addCallback((currentLanguage) => { - const layoutToUse = self.layoutToUse.data; + const layoutToUse = self.layoutToUse; if (layoutToUse === undefined) { return; } - if (this.layoutToUse.data.language.indexOf(currentLanguage) < 0) { + if (this.layoutToUse.language.indexOf(currentLanguage) < 0) { console.log( "Resetting language to", layoutToUse.language[0], diff --git a/UI/Base/Minimap.ts b/UI/Base/Minimap.ts index 963d39db1..32cdadbd6 100644 --- a/UI/Base/Minimap.ts +++ b/UI/Base/Minimap.ts @@ -1,8 +1,8 @@ import BaseUIElement from "../BaseUIElement"; import Loc from "../../Models/Loc"; import BaseLayer from "../../Models/BaseLayer"; -import {BBox} from "../../Logic/GeoOperations"; import {UIEventSource} from "../../Logic/UIEventSource"; +import {BBox} from "../../Logic/BBox"; export interface MinimapOptions { background?: UIEventSource, @@ -30,6 +30,8 @@ export default class Minimap { /** * Construct a minimap */ - public static createMiniMap: (options: MinimapOptions) => (BaseUIElement & MinimapObj) + public static createMiniMap: (options: MinimapOptions) => (BaseUIElement & MinimapObj) = (_) => { + throw "CreateMinimap hasn't been initialized yet. Please call MinimapImplementation.initialize()" + } } \ No newline at end of file diff --git a/UI/Base/MinimapImplementation.ts b/UI/Base/MinimapImplementation.ts index 00fbc0f09..110235437 100644 --- a/UI/Base/MinimapImplementation.ts +++ b/UI/Base/MinimapImplementation.ts @@ -4,10 +4,10 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import Loc from "../../Models/Loc"; import BaseLayer from "../../Models/BaseLayer"; import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; -import {BBox} from "../../Logic/GeoOperations"; import * as L from "leaflet"; import {Map} from "leaflet"; import Minimap, {MinimapObj, MinimapOptions} from "./Minimap"; +import {BBox} from "../../Logic/BBox"; export default class MinimapImplementation extends BaseUIElement implements MinimapObj { private static _nextId = 0; @@ -50,7 +50,7 @@ export default class MinimapImplementation extends BaseUIElement implements Mini if (typeof factor === "number") { bounds = leaflet.getBounds() leaflet.setMaxBounds(bounds.pad(factor)) - }else{ + } else { // @ts-ignore leaflet.setMaxBounds(factor.toLeaflet()) bounds = leaflet.getBounds() @@ -114,8 +114,12 @@ export default class MinimapImplementation extends BaseUIElement implements Mini const self = this; // @ts-ignore const resizeObserver = new ResizeObserver(_ => { - self.InitMap(); - self.leafletMap?.data?.invalidateSize() + try { + self.InitMap(); + self.leafletMap?.data?.invalidateSize() + } catch (e) { + console.error("Could not construct a minimap:", e) + } }); resizeObserver.observe(div); @@ -141,8 +145,12 @@ export default class MinimapImplementation extends BaseUIElement implements Mini const location = this._location; const self = this; let currentLayer = this._background.data.layer() + let latLon = <[number, number]>[location.data?.lat ?? 0, location.data?.lon ?? 0] + if(isNaN(latLon[0]) || isNaN(latLon[1])){ + latLon = [0,0] + } const options = { - center: <[number, number]>[location.data?.lat ?? 0, location.data?.lon ?? 0], + center: latLon, zoom: location.data?.zoom ?? 2, layers: [currentLayer], zoomControl: false, diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index 4a158ec0a..da8114f8c 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -36,6 +36,8 @@ export default class ScrollableFullScreen extends UIElement { this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown) .SetClass("hidden md:block"); this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); + + const self = this; isShown.addCallback(isShown => { if (isShown) { diff --git a/UI/Base/TabbedComponent.ts b/UI/Base/TabbedComponent.ts index b5a33871a..8f71a462a 100644 --- a/UI/Base/TabbedComponent.ts +++ b/UI/Base/TabbedComponent.ts @@ -31,7 +31,7 @@ export class TabbedComponent extends Combine { tabs.push(tab) } - const header = new Combine(tabs).SetClass("block tabs-header-bar") + const header = new Combine(tabs).SetClass("tabs-header-bar") const actualContent = new VariableUiElement( openedTabSrc.map(i => contentElements[i]) ) diff --git a/UI/Base/VariableUIElement.ts b/UI/Base/VariableUIElement.ts index fbc3bb564..7c895b9cb 100644 --- a/UI/Base/VariableUIElement.ts +++ b/UI/Base/VariableUIElement.ts @@ -2,22 +2,23 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import BaseUIElement from "../BaseUIElement"; export class VariableUiElement extends BaseUIElement { - private _element: HTMLElement; + private readonly _contents: UIEventSource; - constructor( - contents: UIEventSource - ) { + constructor(contents: UIEventSource) { super(); + this._contents = contents; - this._element = document.createElement("span"); - const el = this._element; - contents.addCallbackAndRun((contents) => { + } + + protected InnerConstructElement(): HTMLElement { + const el = document.createElement("span"); + this._contents.addCallbackAndRun((contents) => { while (el.firstChild) { el.removeChild(el.lastChild); } if (contents === undefined) { - return el; + return } if (typeof contents === "string") { el.innerHTML = contents; @@ -35,9 +36,6 @@ export class VariableUiElement extends BaseUIElement { } } }); - } - - protected InnerConstructElement(): HTMLElement { - return this._element; + return el; } } diff --git a/UI/BaseUIElement.ts b/UI/BaseUIElement.ts index d0152bbd5..a18b25972 100644 --- a/UI/BaseUIElement.ts +++ b/UI/BaseUIElement.ts @@ -100,6 +100,7 @@ export default abstract class BaseUIElement { throw "ERROR! This is not a correct baseUIElement: " + this.constructor.name } + try { const el = this.InnerConstructElement(); diff --git a/UI/BigComponents/Attribution.ts b/UI/BigComponents/Attribution.ts index 7e70fa367..471556798 100644 --- a/UI/BigComponents/Attribution.ts +++ b/UI/BigComponents/Attribution.ts @@ -7,7 +7,7 @@ import Constants from "../../Models/Constants"; import Loc from "../../Models/Loc"; import {VariableUiElement} from "../Base/VariableUIElement"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; -import {BBox} from "../../Logic/GeoOperations"; +import {BBox} from "../../Logic/BBox"; /** * The bottom right attribution panel in the leaflet map @@ -16,13 +16,13 @@ export default class Attribution extends Combine { constructor(location: UIEventSource, userDetails: UIEventSource, - layoutToUse: UIEventSource, + layoutToUse: LayoutConfig, currentBounds: UIEventSource) { const mapComplete = new Link(`Mapcomplete ${Constants.vNumber}`, 'https://github.com/pietervdvn/MapComplete', true); const reportBug = new Link(Svg.bug_ui().SetClass("small-image"), "https://github.com/pietervdvn/MapComplete/issues", true); - const layoutId = layoutToUse?.data?.id; + const layoutId = layoutToUse?.id; const now = new Date() // Note: getMonth is zero-index, we want 1-index but with one substracted, so it checks out! const startDate = now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate() diff --git a/UI/BigComponents/AttributionPanel.ts b/UI/BigComponents/AttributionPanel.ts index 542326314..c18c8d287 100644 --- a/UI/BigComponents/AttributionPanel.ts +++ b/UI/BigComponents/AttributionPanel.ts @@ -20,11 +20,11 @@ export default class AttributionPanel extends Combine { private static LicenseObject = AttributionPanel.GenerateLicenses(); - constructor(layoutToUse: UIEventSource, contributions: UIEventSource>) { + constructor(layoutToUse: LayoutConfig, contributions: UIEventSource>) { super([ Translations.t.general.attribution.attributionContent, - ((layoutToUse.data.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.data.maintainer}), - layoutToUse.data.credits, + ((layoutToUse.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer}), + layoutToUse.credits, "
", new Attribution(State.state.locationControl, State.state.osmConnection.userDetails, State.state.layoutToUse, State.state.currentBounds), "
", @@ -65,7 +65,7 @@ export default class AttributionPanel extends Combine { "
", AttributionPanel.CodeContributors(), "

", Translations.t.general.attribution.iconAttribution.title.Clone().SetClass("pt-6 pb-3"), "

", - ...Utils.NoNull(Array.from(layoutToUse.data.ExtractImages())) + ...Utils.NoNull(Array.from(layoutToUse.ExtractImages())) .map(AttributionPanel.IconAttribution) ]); this.SetClass("flex flex-col link-underline overflow-hidden") diff --git a/UI/BigComponents/BackgroundSelector.ts b/UI/BigComponents/BackgroundSelector.ts index d13b4e9c0..f5d1a1415 100644 --- a/UI/BigComponents/BackgroundSelector.ts +++ b/UI/BigComponents/BackgroundSelector.ts @@ -25,7 +25,9 @@ export default class BackgroundSelector extends VariableUiElement { if (baseLayers.length <= 1) { return undefined; } - return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer) + return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer, { + select_class: 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' + }) } ) ) diff --git a/UI/BigComponents/DownloadPanel.ts b/UI/BigComponents/DownloadPanel.ts index 746715826..552f6f357 100644 --- a/UI/BigComponents/DownloadPanel.ts +++ b/UI/BigComponents/DownloadPanel.ts @@ -5,7 +5,7 @@ import State from "../../State"; import {Utils} from "../../Utils"; import Combine from "../Base/Combine"; import CheckBoxes from "../Input/Checkboxes"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; +import {GeoOperations} from "../../Logic/GeoOperations"; import Toggle from "../Input/Toggle"; import Title from "../Base/Title"; import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"; @@ -13,19 +13,20 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import SimpleMetaTagger from "../../Logic/SimpleMetaTagger"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {meta} from "@turf/turf"; +import {BBox} from "../../Logic/BBox"; export class DownloadPanel extends Toggle { constructor() { const state: { featurePipeline: FeaturePipeline, - layoutToUse: UIEventSource, + layoutToUse: LayoutConfig, currentBounds: UIEventSource } = State.state const t = Translations.t.general.download - const name = State.state.layoutToUse.data.id; + const name = State.state.layoutToUse.id; const includeMetaToggle = new CheckBoxes([t.includeMetaData.Clone()]) const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0) diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index 6e3fae5f7..ffcdbc3c9 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -7,8 +7,6 @@ import Combine from "../Base/Combine"; import Translations from "../i18n/Translations"; import {Translation} from "../i18n/Translation"; import Svg from "../../Svg"; -import {TagsFilter} from "../../Logic/Tags/TagsFilter"; -import {And} from "../../Logic/Tags/And"; import {UIEventSource} from "../../Logic/UIEventSource"; import BaseUIElement from "../BaseUIElement"; import State from "../../State"; @@ -16,11 +14,6 @@ import FilteredLayer from "../../Models/FilteredLayer"; import BackgroundSelector from "./BackgroundSelector"; import FilterConfig from "../../Models/ThemeConfig/FilterConfig"; - -/** - * Shows the filter - */ - export default class FilterView extends VariableUiElement { constructor(filteredLayer: UIEventSource) { const backgroundSelector = new Toggle( @@ -101,26 +94,52 @@ export default class FilterView extends VariableUiElement { return undefined; } - let listFilterElements: [BaseUIElement, UIEventSource][] = layer.filters.map( + const filterIndexes = new Map() + layer.filters.forEach((f, i) => filterIndexes.set(f.id, i)) + + let listFilterElements: [BaseUIElement, UIEventSource<{ filter: FilterConfig, selected: number }>][] = layer.filters.map( FilterView.createFilter ); - const update = () => { - let listTagsFilters = Utils.NoNull( - listFilterElements.map((input) => input[1].data) - ); - flayer.appliedFilters.setData(new And(listTagsFilters)); - }; + listFilterElements.forEach((inputElement, i) => + inputElement[1].addCallback((changed) => { + const oldValue = flayer.appliedFilters.data + + if(changed === undefined){ + // Lets figure out which filter should be removed + // We know this inputElement corresponds with layer.filters[i] + // SO, if there is a value in 'oldValue' with this filter, we have to recalculated + if(!oldValue.some(f => f.filter === layer.filters[i])){ + // The filter to remove is already gone, we can stop + return; + } + }else if(oldValue.some(f => f.filter === changed.filter && f.selected === changed.selected)){ + // The changed value is already there + return; + } + const listTagsFilters = Utils.NoNull( + listFilterElements.map((input) => input[1].data) + ); - listFilterElements.forEach((inputElement) => - inputElement[1].addCallback((_) => update()) + console.log(listTagsFilters, oldValue) + flayer.appliedFilters.setData(listTagsFilters); + }) ); flayer.appliedFilters.addCallbackAndRun(appliedFilters => { - if (appliedFilters === undefined || appliedFilters.and.length === 0) { - listFilterElements.forEach(filter => filter[1].setData(undefined)) - return + for (let i = 0; i < layer.filters.length; i++){ + const filter = layer.filters[i]; + let foundMatch = undefined + for (const appliedFilter of appliedFilters) { + if(appliedFilter.filter === filter){ + foundMatch = appliedFilter + break; + } + } + + listFilterElements[i][1].setData(foundMatch) } + }) return new Combine(listFilterElements.map(input => input[0].SetClass("mt-3"))) @@ -128,7 +147,7 @@ export default class FilterView extends VariableUiElement { } - private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource] { + private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<{ filter: FilterConfig, selected: number }>] { if (filterConfig.options.length === 1) { let option = filterConfig.options[0]; @@ -136,26 +155,42 @@ export default class FilterView extends VariableUiElement { const iconUnselected = Svg.checkbox_empty_svg().SetClass("block mr-2"); const toggle = new Toggle( - new Combine([icon, option.question.Clone()]).SetClass("flex"), - new Combine([iconUnselected, option.question.Clone()]).SetClass("flex") + new Combine([icon, option.question.Clone().SetClass("block")]).SetClass("flex"), + new Combine([iconUnselected, option.question.Clone().SetClass("block")]).SetClass("flex") ) .ToggleOnClick() .SetClass("block m-1") - return [toggle, toggle.isEnabled.map(enabled => enabled ? option.osmTags : undefined, [], tags => tags !== undefined)] + const selected = { + filter: filterConfig, + selected: 0 + } + return [toggle, toggle.isEnabled.map(enabled => enabled ? selected : undefined, [], + f => f?.filter === filterConfig && f?.selected === 0) + ] } let options = filterConfig.options; + const values = options.map((f, i) => ({ + filter: filterConfig, selected: i + })) const radio = new RadioButton( options.map( - (option) => - new FixedInputElement(option.question.Clone(), option.osmTags) + (option, i) => + new FixedInputElement(option.question.Clone().SetClass("block"), i) ), { dontStyle: true } ); - return [radio, radio.GetValue()] + return [radio, + radio.GetValue().map( + i => values[i], + [], + selected => { + return selected?.selected + } + )] } } diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index a4a3e826a..8ee36ecec 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -1,7 +1,5 @@ import State from "../../State"; import ThemeIntroductionPanel from "./ThemeIntroductionPanel"; -import * as personal from "../../assets/themes/personal/personal.json"; -import PersonalLayersPanel from "./PersonalLayersPanel"; import Svg from "../../Svg"; import Translations from "../i18n/Translations"; import ShareScreen from "./ShareScreen"; @@ -21,7 +19,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { constructor(isShown: UIEventSource) { - const layoutToUse = State.state.layoutToUse.data; + const layoutToUse = State.state.layoutToUse; super( () => layoutToUse.title.Clone(), () => FullWelcomePaneWithTabs.GenerateContents(layoutToUse, State.state.osmConnection.userDetails, isShown), @@ -32,9 +30,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { private static ConstructBaseTabs(layoutToUse: LayoutConfig, isShown: UIEventSource): { header: string | BaseUIElement; content: BaseUIElement }[] { let welcome: BaseUIElement = new ThemeIntroductionPanel(isShown); - if (layoutToUse.id === personal.id) { - welcome = new PersonalLayersPanel(); - } + const tabs: { header: string | BaseUIElement, content: BaseUIElement }[] = [ {header: ``, content: welcome}, { diff --git a/UI/BigComponents/ImportButton.ts b/UI/BigComponents/ImportButton.ts index f62b912fd..160405264 100644 --- a/UI/BigComponents/ImportButton.ts +++ b/UI/BigComponents/ImportButton.ts @@ -31,14 +31,14 @@ export default class ImportButton extends Toggle { const button = new SubtleButton(imageUrl, message) - button.onClick(() => { + button.onClick(async () => { if (isImported.data) { return } originalTags.data["_imported"] = "yes" originalTags.ping() // will set isImported as per its definition const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon) - State.state.changes.applyAction(newElementAction) + await State.state.changes.applyAction(newElementAction) State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( newElementAction.newElementId )) diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index b3e848d4d..7ee2a74e6 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -11,8 +11,8 @@ import AllDownloads from "./AllDownloads"; import FilterView from "./FilterView"; import {UIEventSource} from "../../Logic/UIEventSource"; import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"; -import {BBox} from "../../Logic/GeoOperations"; import Loc from "../../Models/Loc"; +import {BBox} from "../../Logic/BBox"; export default class LeftControls extends Combine { diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 9d8fa44f9..01e4b9f95 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -126,7 +126,7 @@ export default class MoreScreen extends Combine { if (layout.hideFromOverview) { return undefined; } - if (layout.id === State.state.layoutToUse.data?.id) { + if (layout.id === State.state.layoutToUse?.id) { return undefined; } diff --git a/UI/BigComponents/PersonalLayersPanel.ts b/UI/BigComponents/PersonalLayersPanel.ts deleted file mode 100644 index e5a41b733..000000000 --- a/UI/BigComponents/PersonalLayersPanel.ts +++ /dev/null @@ -1,120 +0,0 @@ -import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts"; -import Svg from "../../Svg"; -import State from "../../State"; -import Combine from "../Base/Combine"; -import Toggle from "../Input/Toggle"; -import {SubtleButton} from "../Base/SubtleButton"; -import Translations from "../i18n/Translations"; -import BaseUIElement from "../BaseUIElement"; -import {VariableUiElement} from "../Base/VariableUIElement"; -import {UIEventSource} from "../../Logic/UIEventSource"; -import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; - -export default class PersonalLayersPanel extends VariableUiElement { - - constructor() { - super( - State.state.installedThemes.map(installedThemes => { - const t = Translations.t.favourite; - - // Lets get all the layers - const allThemes = AllKnownLayouts.layoutsList.concat(installedThemes.map(layout => layout.layout)) - .filter(theme => !theme.hideFromOverview) - - const allLayers = [] - { - const seenLayers = new Set() - for (const layers of allThemes.map(theme => theme.layers)) { - for (const layer of layers) { - if (seenLayers.has(layer.id)) { - continue - } - seenLayers.add(layer.id) - allLayers.push(layer) - } - } - } - - // Time to create a panel based on them! - const panel: BaseUIElement = new Combine(allLayers.map(PersonalLayersPanel.CreateLayerToggle)); - - - return new Toggle( - new Combine([ - t.panelIntro.Clone(), - panel - ]).SetClass("flex flex-col"), - new SubtleButton( - Svg.osm_logo_ui(), - t.loginNeeded.Clone().SetClass("text-center") - ).onClick(() => State.state.osmConnection.AttemptLogin()), - State.state.osmConnection.isLoggedIn - ) - }) - ) - } - - /*** - * Creates a toggle for the given layer, which'll update State.state.favouriteLayers right away - * @param layer - * @constructor - * @private - */ - private static CreateLayerToggle(layer: LayerConfig): Toggle { - let icon: BaseUIElement = new Combine([layer.GenerateLeafletStyle( - new UIEventSource({id: "node/-1"}), - false - ).icon.html]).SetClass("relative") - let iconUnset = new Combine([layer.GenerateLeafletStyle( - new UIEventSource({id: "node/-1"}), - false - ).icon.html]).SetClass("relative") - - iconUnset.SetStyle("opacity:0.1") - - let name = layer.name; - if (name === undefined) { - return undefined; - } - const content = new Combine([ - Translations.WT(name).Clone().SetClass("font-bold"), - Translations.WT(layer.description)?.Clone() - ]).SetClass("flex flex-col") - - const contentUnselected = new Combine([ - Translations.WT(name).Clone().SetClass("font-bold"), - Translations.WT(layer.description)?.Clone() - ]).SetClass("flex flex-col line-through") - - return new Toggle( - new SubtleButton( - icon, - content), - new SubtleButton( - iconUnset, - contentUnselected - ), - State.state.favouriteLayers.map(favLayers => { - return favLayers.indexOf(layer.id) >= 0 - }, [], (selected, current) => { - if (!selected && current.indexOf(layer.id) <= 0) { - // Not selected and not contained: nothing to change: we return current as is - return current; - } - if (selected && current.indexOf(layer.id) >= 0) { - // Selected and contained: this is fine! - return current; - } - const clone = [...current] - if (selected) { - clone.push(layer.id) - } else { - clone.splice(clone.indexOf(layer.id), 1) - } - return clone - }) - ).ToggleOnClick(); - } - - -} \ No newline at end of file diff --git a/UI/BigComponents/ShareScreen.ts b/UI/BigComponents/ShareScreen.ts index 9b97ef441..32e1b0ce0 100644 --- a/UI/BigComponents/ShareScreen.ts +++ b/UI/BigComponents/ShareScreen.ts @@ -17,7 +17,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; export default class ShareScreen extends Combine { constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) { - layout = layout ?? State.state?.layoutToUse?.data; + layout = layout ?? State.state?.layoutToUse; layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition; const tr = Translations.t.general.sharescreen; diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index 57f651e9a..ad6a73ec5 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -19,8 +19,7 @@ import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction"; import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject"; import PresetConfig from "../../Models/ThemeConfig/PresetConfig"; import FilteredLayer from "../../Models/FilteredLayer"; -import {And} from "../../Logic/Tags/And"; -import {BBox} from "../../Logic/GeoOperations"; +import {BBox} from "../../Logic/BBox"; /* * The SimpleAddUI is a single panel, which can have multiple states: @@ -56,10 +55,9 @@ export default class SimpleAddUI extends Toggle { const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset) - function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { - console.trace("Creating a new point") + async function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay}) - State.state.changes.applyAction(newElementAction) + await State.state.changes.applyAction(newElementAction) selectedPreset.setData(undefined) isShown.setData(false) State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( @@ -224,14 +222,32 @@ export default class SimpleAddUI extends Toggle { ] ).SetClass("flex flex-col") ).onClick(() => { - preset.layerToAddTo.appliedFilters.setData(new And([])) + preset.layerToAddTo.appliedFilters.setData([]) cancel() }) const disableFiltersOrConfirm = new Toggle( openLayerOrConfirm, disableFilter, - preset.layerToAddTo.appliedFilters.map(filters => filters === undefined || filters.normalize().and.length === 0) + preset.layerToAddTo.appliedFilters.map(filters => { + if(filters === undefined || filters.length === 0){ + return true; + } + for (const filter of filters) { + if(filter.selected === 0 && filter.filter.options.length === 1){ + return false; + } + if(filter.selected !== undefined){ + const tags = filter.filter.options[filter.selected].osmTags + if(tags !== undefined && tags["and"]?.length !== 0){ + // This actually doesn't filter anything at all + return false; + } + } + } + return true + + }) ) diff --git a/UI/BigComponents/ThemeIntroductionPanel.ts b/UI/BigComponents/ThemeIntroductionPanel.ts index 8c4add4d9..75c5b6f55 100644 --- a/UI/BigComponents/ThemeIntroductionPanel.ts +++ b/UI/BigComponents/ThemeIntroductionPanel.ts @@ -2,21 +2,17 @@ import State from "../../State"; import Combine from "../Base/Combine"; import LanguagePicker from "../LanguagePicker"; import Translations from "../i18n/Translations"; -import {VariableUiElement} from "../Base/VariableUIElement"; import Toggle from "../Input/Toggle"; import {SubtleButton} from "../Base/SubtleButton"; import Svg from "../../Svg"; import {UIEventSource} from "../../Logic/UIEventSource"; -export default class ThemeIntroductionPanel extends VariableUiElement { +export default class ThemeIntroductionPanel extends Combine { constructor(isShown: UIEventSource) { + const layout = State.state.layoutToUse - const languagePicker = - new VariableUiElement( - State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone())) - ) - ; + const languagePicker = LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone()) const toTheMap = new SubtleButton( undefined, @@ -53,8 +49,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { State.state.featureSwitchUserbadge ) - - super(State.state.layoutToUse.map(layout => new Combine([ + super([ layout.description.Clone(), "

", toTheMap, @@ -63,7 +58,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { "
", languagePicker, ...layout.CustomCodeSnippets() - ]))) + ]) this.SetClass("link-underline") } diff --git a/UI/BigComponents/UserBadge.ts b/UI/BigComponents/UserBadge.ts index 297e470e3..3aef14044 100644 --- a/UI/BigComponents/UserBadge.ts +++ b/UI/BigComponents/UserBadge.ts @@ -47,7 +47,7 @@ export default class UserBadge extends Toggle { }); const linkStyle = "flex items-baseline" - const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.language) ?? new FixedUiElement("")) + const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.language) ?? new FixedUiElement("")) .SetStyle("width:min-content;"); let messageSpan = diff --git a/UI/ExportPDF.ts b/UI/ExportPDF.ts index f1a113daa..54879b9b2 100644 --- a/UI/ExportPDF.ts +++ b/UI/ExportPDF.ts @@ -5,7 +5,6 @@ import {SimpleMapScreenshoter} from "leaflet-simple-map-screenshoter"; import {UIEventSource} from "../Logic/UIEventSource"; import Minimap from "./Base/Minimap"; import Loc from "../Models/Loc"; -import {BBox} from "../Logic/GeoOperations"; import BaseLayer from "../Models/BaseLayer"; import {FixedUiElement} from "./Base/FixedUiElement"; import Translations from "./i18n/Translations"; @@ -14,6 +13,7 @@ import Constants from "../Models/Constants"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; import ShowDataLayer from "./ShowDataLayer/ShowDataLayer"; +import {BBox} from "../Logic/BBox"; /** * Creates screenshoter to take png screenshot * Creates jspdf and downloads it diff --git a/UI/Image/AttributedImage.ts b/UI/Image/AttributedImage.ts index 7614077c5..919a9ac17 100644 --- a/UI/Image/AttributedImage.ts +++ b/UI/Image/AttributedImage.ts @@ -1,30 +1,19 @@ import Combine from "../Base/Combine"; import Attribution from "./Attribution"; import Img from "../Base/Img"; -import ImageAttributionSource from "../../Logic/ImageProviders/ImageAttributionSource"; +import {ProvidedImage} from "../../Logic/ImageProviders/ImageProvider"; import BaseUIElement from "../BaseUIElement"; -import {VariableUiElement} from "../Base/VariableUIElement"; -import Loading from "../Base/Loading"; export class AttributedImage extends Combine { - constructor(urlSource: string, imgSource: ImageAttributionSource) { - const preparedUrl = imgSource.PrepareUrl(urlSource) + constructor(imageInfo: ProvidedImage) { let img: BaseUIElement; let attr: BaseUIElement - if (typeof preparedUrl === "string") { - img = new Img(urlSource); - attr = new Attribution(imgSource.GetAttributionFor(urlSource), imgSource.SourceIcon()) - } else { - img = new VariableUiElement(preparedUrl.map(url => { - if(url === undefined){ - return new Loading() - } - return new Img(url, false, {fallbackImage: './assets/svg/blocked.svg'}); - })) - attr = new VariableUiElement(preparedUrl.map(_ => new Attribution(imgSource.GetAttributionFor(urlSource), imgSource.SourceIcon()))) - } + img = new Img(imageInfo.url); + attr = new Attribution(imageInfo.provider.GetAttributionFor(imageInfo.url), + imageInfo.provider.SourceIcon(), + ) super([img, attr]); diff --git a/UI/Image/Attribution.ts b/UI/Image/Attribution.ts index 30040482f..f57911e93 100644 --- a/UI/Image/Attribution.ts +++ b/UI/Image/Attribution.ts @@ -3,7 +3,7 @@ import Translations from "../i18n/Translations"; import BaseUIElement from "../BaseUIElement"; import {VariableUiElement} from "../Base/VariableUIElement"; import {UIEventSource} from "../../Logic/UIEventSource"; -import {LicenseInfo} from "../../Logic/ImageProviders/Wikimedia"; +import {LicenseInfo} from "../../Logic/ImageProviders/LicenseInfo"; export default class Attribution extends VariableUiElement { @@ -13,17 +13,16 @@ export default class Attribution extends VariableUiElement { } super( license.map((license: LicenseInfo) => { - - if (license?.artist === undefined) { - return undefined; + if(license === undefined){ + return undefined } - + return new Combine([ icon?.SetClass("block left").SetStyle("height: 2em; width: 2em; padding-right: 0.5em;"), new Combine([ - Translations.W(license.artist).SetClass("block font-bold"), - Translations.W((license.license ?? "") === "" ? "CC0" : (license.license ?? "")) + Translations.W(license?.artist ?? ".").SetClass("block font-bold"), + Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? "")) ]).SetClass("flex flex-col") ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg") diff --git a/UI/Image/DeleteImage.ts b/UI/Image/DeleteImage.ts index a5ee19266..800eec53c 100644 --- a/UI/Image/DeleteImage.ts +++ b/UI/Image/DeleteImage.ts @@ -15,15 +15,15 @@ export default class DeleteImage extends Toggle { const isDeletedBadge = Translations.t.image.isDeleted.Clone() .SetClass("rounded-full p-1") .SetStyle("color:white;background:#ff8c8c") - .onClick(() => { - State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) + .onClick(async() => { + await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) }); const deleteButton = Translations.t.image.doDelete.Clone() .SetClass("block w-full pl-4 pr-4") .SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;") - .onClick(() => { - State.state?.changes?.applyAction( + .onClick( async() => { + await State.state?.changes?.applyAction( new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data) ) }); @@ -48,7 +48,7 @@ export default class DeleteImage extends Toggle { tags.map(tags => (tags[key] ?? "") !== "") ), undefined /*Login (and thus editing) is disabled*/, - State.state?.featureSwitchUserbadge ?? new UIEventSource(true) + State.state.osmConnection.isLoggedIn ) this.SetClass("cursor-pointer") } diff --git a/UI/Image/ImageCarousel.ts b/UI/Image/ImageCarousel.ts index 4e7d032d2..c20f52080 100644 --- a/UI/Image/ImageCarousel.ts +++ b/UI/Image/ImageCarousel.ts @@ -4,29 +4,35 @@ import Combine from "../Base/Combine"; import DeleteImage from "./DeleteImage"; import {AttributedImage} from "./AttributedImage"; import BaseUIElement from "../BaseUIElement"; -import Img from "../Base/Img"; import Toggle from "../Input/Toggle"; -import {Wikimedia} from "../../Logic/ImageProviders/Wikimedia"; -import {Imgur} from "../../Logic/ImageProviders/Imgur"; -import {Mapillary} from "../../Logic/ImageProviders/Mapillary"; +import ImageProvider from "../../Logic/ImageProviders/ImageProvider"; export class ImageCarousel extends Toggle { - constructor(images: UIEventSource<{ key: string, url: string }[]>, tags: UIEventSource) { - const uiElements = images.map((imageURLS: { key: string, url: string }[]) => { + constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider }[]>, tags: UIEventSource) { + const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => { const uiElements: BaseUIElement[] = []; for (const url of imageURLS) { - let image = ImageCarousel.CreateImageElement(url.url) - if (url.key !== undefined) { - image = new Combine([ - image, - new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3") - ]).SetClass("relative"); + + try { + + let image = new AttributedImage(url) + + if (url.key !== undefined) { + image = new Combine([ + image, + new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3") + ]).SetClass("relative"); + } + image + .SetClass("w-full block") + .SetStyle("min-width: 50px; background: grey;") + uiElements.push(image); + } catch (e) { + console.error("Could not generate image element for", url.url, "due to", e) } - image - .SetClass("w-full block") - .SetStyle("min-width: 50px; background: grey;") - uiElements.push(image); + + } return uiElements; }); @@ -38,33 +44,4 @@ export class ImageCarousel extends Toggle { ) this.SetClass("block w-full"); } - - /*** - * Creates either a 'simpleimage' or a 'wikimediaimage' based on the string - * @param url - * @constructor - */ - private static CreateImageElement(url: string): BaseUIElement { - // @ts-ignore - let attrSource: ImageAttributionSource = undefined; - if (url.startsWith("File:")) { - attrSource = Wikimedia.singleton - } else if (url.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { - attrSource = Wikimedia.singleton; - } else if (url.toLowerCase().startsWith("https://i.imgur.com/")) { - attrSource = Imgur.singleton - } else if (url.toLowerCase().startsWith("https://www.mapillary.com/map/im/")) { - attrSource = Mapillary.singleton - } else { - return new Img(url); - } - - try { - return new AttributedImage(url, attrSource) - } catch (e) { - console.error("Could not create an image: ", e) - return undefined; - } - - } } \ No newline at end of file diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 2a8053523..4eec0b85c 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -29,10 +29,10 @@ export class ImageUploadFlow extends Toggle { key = imagePrefix + ":" + freeIndex; } console.log("Adding image:" + key, url); - State.state.changes + Promise.resolve(State.state.changes .applyAction(new ChangeTagAction( tags.id, new Tag(key, url), tagsSource.data - )) + ))) }) @@ -55,7 +55,7 @@ export class ImageUploadFlow extends Toggle { const tags = tagsSource.data; - const layout = State.state?.layoutToUse?.data + const layout = State.state?.layoutToUse let matchingLayer: LayerConfig = undefined for (const layer of layout?.layers ?? []) { if (layer.source.osmTags.matchesProperties(tags)) { diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index a350e38d3..db96cf7be 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -7,12 +7,13 @@ import Combine from "../Base/Combine"; import Svg from "../../Svg"; import State from "../../State"; import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; -import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; -import * as L from "leaflet"; +import {GeoOperations} from "../../Logic/GeoOperations"; import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {BBox} from "../../Logic/BBox"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; export default class LocationInput extends InputElement { @@ -39,7 +40,7 @@ export default class LocationInput extends InputElement { private readonly _maxSnapDistance: number private readonly _snappedPointTags: any; private readonly _bounds: UIEventSource; - public readonly _matching_layer: UIEventSource; + public readonly _matching_layer: LayerConfig; constructor(options: { mapBackground?: UIEventSource, @@ -63,18 +64,17 @@ export default class LocationInput extends InputElement { if (self._snappedPointTags !== undefined) { - this._matching_layer = State.state.layoutToUse.map(layout => { + const layout = State.state.layoutToUse - for (const layer of layout.layers) { - if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { - return layer - } + let matchingLayer = LocationInput.matchLayer + for (const layer of layout.layers) { + if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { + matchingLayer = layer } - console.error("No matching layer found for tags ", self._snappedPointTags) - return LocationInput.matchLayer - }) + } + this._matching_layer = matchingLayer; } else { - this._matching_layer = new UIEventSource(LocationInput.matchLayer) + this._matching_layer = LocationInput.matchLayer } this._snappedPoint = options.centerLocation.map(loc => { @@ -125,7 +125,7 @@ export default class LocationInput extends InputElement { }) } - this.mapBackground = options.mapBackground ?? State.state.backgroundLayer ?? new UIEventSource(AvailableBaseLayers.osmCarto) + this.mapBackground = options.mapBackground ?? State.state?.backgroundLayer ?? new UIEventSource(AvailableBaseLayers.osmCarto) this.SetClass("block h-full") } @@ -144,7 +144,7 @@ export default class LocationInput extends InputElement { { location: this._centerLocation, background: this.mapBackground, - attribution: this.mapBackground !== State.state.backgroundLayer, + attribution: this.mapBackground !== State.state?.backgroundLayer, lastClickLocation: clickLocation, bounds: this._bounds } @@ -176,11 +176,10 @@ export default class LocationInput extends InputElement { enablePopups: false, zoomToFeatures: false, leafletMap: map.leafletMap, - layerToShow: this._matching_layer.data + layerToShow: this._matching_layer }) } - this.mapBackground.map(layer => { const leaflet = map.leafletMap.data if (leaflet === undefined || layer === undefined) { @@ -192,20 +191,31 @@ export default class LocationInput extends InputElement { leaflet.setZoom(layer.max_zoom - 1) }, [map.leafletMap]) + + const animatedHand = Svg.hand_ui() + .SetStyle("width: 2rem; height: unset;") + .SetClass("hand-drag-animation block pointer-events-none") + return new Combine([ new Combine([ Svg.move_arrows_ui() .SetClass("block relative pointer-events-none") .SetStyle("left: -2.5rem; top: -2.5rem; width: 5rem; height: 5rem") - ]).SetClass("block w-0 h-0 z-10 relative") - .SetStyle("background: rgba(255, 128, 128, 0.21); left: 50%; top: 50%"), + ]).SetClass("block w-0 h-0 z-10 relative") + .SetStyle("background: rgba(255, 128, 128, 0.21); left: 50%; top: 50%; opacity: 0.5"), + + new Combine([ + animatedHand]) + .SetClass("block w-0 h-0 z-10 relative") + .SetStyle("left: calc(50% + 3rem); top: calc(50% + 2rem); opacity: 0.7"), + map .SetClass("z-0 relative block w-full h-full bg-gray-100") ]).ConstructElement(); } catch (e) { console.error("Could not generate LocationInputElement:", e) - return undefined; + return new FixedUiElement("Constructing a locationInput failed due to" + e).SetClass("alert").ConstructElement(); } } diff --git a/UI/Popup/DeleteWizard.ts b/UI/Popup/DeleteWizard.ts index b81e82f47..6025ff890 100644 --- a/UI/Popup/DeleteWizard.ts +++ b/UI/Popup/DeleteWizard.ts @@ -51,14 +51,14 @@ export default class DeleteWizard extends Toggle { const confirm = new UIEventSource(false) - function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { + async function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { if (reason !== undefined) { tagsToApply.splice(0, 0, { k: "fixme", v: `A mapcomplete user marked this feature to be deleted (${reason})` }) } - (State.state?.changes ?? new Changes()) + await (State.state?.changes ?? new Changes()) .applyAction(new ChangeTagAction( id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data )) diff --git a/UI/Popup/EditableTagRendering.ts b/UI/Popup/EditableTagRendering.ts index 4e5c313f5..4c5a13ea5 100644 --- a/UI/Popup/EditableTagRendering.ts +++ b/UI/Popup/EditableTagRendering.ts @@ -31,8 +31,10 @@ export default class EditableTagRendering extends Toggle { const answerWithEditButton = new Combine([answer, - new Toggle(editButton, undefined, State.state.osmConnection.isLoggedIn)]) - .SetClass("flex justify-between w-full") + new Toggle(editButton, + undefined, + State.state.osmConnection.isLoggedIn) + ]).SetClass("flex justify-between w-full") const cancelbutton = diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts index 01fb00d05..17e1bd013 100644 --- a/UI/Popup/SplitRoadWizard.ts +++ b/UI/Popup/SplitRoadWizard.ts @@ -5,7 +5,7 @@ import {SubtleButton} from "../Base/SubtleButton"; import Minimap from "../Base/Minimap"; import State from "../../State"; import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; +import {GeoOperations} from "../../Logic/GeoOperations"; import {LeafletMouseEvent} from "leaflet"; import Combine from "../Base/Combine"; import {Button} from "../Base/Button"; @@ -15,6 +15,7 @@ import Title from "../Base/Title"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {BBox} from "../../Logic/BBox"; export default class SplitRoadWizard extends Toggle { private static splitLayerStyling = new LayerConfig({ @@ -71,7 +72,7 @@ export default class SplitRoadWizard extends Toggle { }) new ShowDataMultiLayer({ - features: new StaticFeatureSource([roadElement]), + features: new StaticFeatureSource([roadElement], false), layers: State.state.filteredLayers, leafletMap: miniMap.leafletMap, enablePopups: false, diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 5f0881d29..ea6839e14 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -58,10 +58,10 @@ export default class TagRenderingQuestion extends Combine { console.error("MultiAnswer failed - probably not a single option was possible", configuration) throw "MultiAnswer failed - probably not a single option was possible" } - const save = () => { + const save = async () => { const selection = inputElement.GetValue().data; if (selection) { - (State.state?.changes ?? new Changes()) + await (State.state?.changes ?? new Changes()) .applyAction(new ChangeTagAction( tags.data.id, selection, tags.data )) diff --git a/UI/ShowDataLayer/ShowDataLayer.ts b/UI/ShowDataLayer/ShowDataLayer.ts index cdda7889b..ade1860ae 100644 --- a/UI/ShowDataLayer/ShowDataLayer.ts +++ b/UI/ShowDataLayer/ShowDataLayer.ts @@ -17,6 +17,7 @@ export default class ShowDataLayer { // Used to generate a fresh ID when needed private _cleanCount = 0; private geoLayer = undefined; + private isDirty = false; /** * If the selected element triggers, this is used to lookup the correct layer and to open the popup @@ -37,41 +38,72 @@ export default class ShowDataLayer { this._layerToShow = options.layerToShow; const self = this; + options.leafletMap.addCallbackAndRunD(_ => { + self.update(options) + } + ); + features.addCallback(_ => self.update(options)); - options.leafletMap.addCallback(_ => self.update(options)); - this.update(options); + options.doShowLayer?.addCallbackAndRun(doShow => { + const mp = options.leafletMap.data; + if (mp == undefined) { + return; + } + if (doShow) { + if (self.isDirty) { + self.update(options) + } else { + mp.addLayer(this.geoLayer) + } + } else { + if(this.geoLayer !== undefined){ + mp.removeLayer(this.geoLayer) + } + } + }) + State.state.selectedElement.addCallbackAndRunD(selected => { if (self._leafletMap.data === undefined) { return; } const v = self.leafletLayersPerId.get(selected.properties.id) - if(v === undefined){return;} + if (v === undefined) { + return; + } const leafletLayer = v.leafletlayer const feature = v.feature if (leafletLayer.getPopup().isOpen()) { return; } - if (selected.properties.id === feature.properties.id) { - // A small sanity check to prevent infinite loops: - if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again - && feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too - ) { - leafletLayer.openPopup() - } - if (feature.id !== feature.properties.id) { - console.trace("Not opening the popup for", feature) - } - + if (selected.properties.id !== feature.properties.id) { + return; + } + + if (feature.id !== feature.properties.id) { + // Probably a feature which has renamed + console.trace("Not opening the popup for", feature) + return; + } + if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again + && feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too + ) { + console.log("Opening popup of feature", feature) + leafletLayer.openPopup() } }) + } - private update(options) { + private update(options: ShowDataLayerOptions) { if (this._features.data === undefined) { return; } + this.isDirty = true; + if (options?.doShowLayer?.data === false) { + return; + } const mp = options.leafletMap.data; if (mp === undefined) { @@ -83,21 +115,30 @@ export default class ShowDataLayer { mp.removeLayer(this.geoLayer); } - this.geoLayer= this.CreateGeojsonLayer() + const self = this; + const data = { + type: "FeatureCollection", + features: [] + } + // @ts-ignore + this.geoLayer = L.geoJSON(data, { + style: feature => self.createStyleFor(feature), + pointToLayer: (feature, latLng) => self.pointToLayer(feature, latLng), + onEachFeature: (feature, leafletLayer) => self.postProcessFeature(feature, leafletLayer) + }); + const allFeats = this._features.data; for (const feat of allFeats) { if (feat === undefined) { continue } - try{ + try { this.geoLayer.addData(feat); - }catch(e){ + } catch (e) { console.error("Could not add ", feat, "to the geojson layer in leaflet") } } - mp.addLayer(this.geoLayer) - if (options.zoomToFeatures ?? false) { try { mp.fitBounds(this.geoLayer.getBounds(), {animate: false}) @@ -105,6 +146,11 @@ export default class ShowDataLayer { console.error(e) } } + + if (options.doShowLayer?.data ?? true) { + mp.addLayer(this.geoLayer) + } + this.isDirty = false; } @@ -125,7 +171,10 @@ export default class ShowDataLayer { return; } - const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : State.state.allElements.getEventSourceById(feature.properties.id) + let tagSource = State.state.allElements.getEventSourceById(feature.properties.id) + if(tagSource === undefined){ + tagSource = new UIEventSource(feature.properties) + } const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) const style = layer.GenerateLeafletStyle(tagSource, clickable); const baseElement = style.icon.html; @@ -193,22 +242,9 @@ export default class ShowDataLayer { infobox.Activate(); }); + // Add the feature to the index to open the popup when needed this.leafletLayersPerId.set(feature.properties.id, {feature: feature, leafletlayer: leafletLayer}) - } - - private CreateGeojsonLayer(): L.Layer { - const self = this; - const data = { - type: "FeatureCollection", - features: [] - } - // @ts-ignore - return L.geoJSON(data, { - style: feature => self.createStyleFor(feature), - pointToLayer: (feature, latLng) => self.pointToLayer(feature, latLng), - onEachFeature: (feature, leafletLayer) => self.postProcessFeature(feature, leafletLayer) - }); } diff --git a/UI/ShowDataLayer/ShowDataLayerOptions.ts b/UI/ShowDataLayer/ShowDataLayerOptions.ts index 349472351..2323ce067 100644 --- a/UI/ShowDataLayer/ShowDataLayerOptions.ts +++ b/UI/ShowDataLayer/ShowDataLayerOptions.ts @@ -6,4 +6,5 @@ export interface ShowDataLayerOptions { leafletMap: UIEventSource, enablePopups?: true | boolean, zoomToFeatures?: false | boolean, + doShowLayer?: UIEventSource } \ No newline at end of file diff --git a/UI/ShowDataLayer/ShowTileInfo.ts b/UI/ShowDataLayer/ShowTileInfo.ts new file mode 100644 index 000000000..1bb636727 --- /dev/null +++ b/UI/ShowDataLayer/ShowTileInfo.ts @@ -0,0 +1,61 @@ +import FeatureSource, {Tiled} from "../../Logic/FeatureSource/FeatureSource"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import ShowDataLayer from "./ShowDataLayer"; +import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; +import {GeoOperations} from "../../Logic/GeoOperations"; +import {Tiles} from "../../Models/TileRange"; +import * as clusterstyle from "../../assets/layers/cluster_style/cluster_style.json" +export default class ShowTileInfo { + public static readonly styling = new LayerConfig( + clusterstyle, "tileinfo", true) + + constructor(options: { + source: FeatureSource & Tiled, leafletMap: UIEventSource, layer?: LayerConfig, + doShowLayer?: UIEventSource + }) { + + + const source = options.source + const metaFeature: UIEventSource = + source.features.map(features => { + const bbox = source.bbox + const [z, x, y] = Tiles.tile_from_index(source.tileIndex) + const box = { + "type": "Feature", + "properties": { + "z": z, + "x": x, + "y": y, + "tileIndex": source.tileIndex, + "source": source.name, + "count": features.length, + tileId: source.name + "/" + source.tileIndex + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [bbox.minLon, bbox.minLat], + [bbox.minLon, bbox.maxLat], + [bbox.maxLon, bbox.maxLat], + [bbox.maxLon, bbox.minLat], + [bbox.minLon, bbox.minLat] + ] + ] + } + } + const center = GeoOperations.centerpoint(box) + return [box, center] + }) + + new ShowDataLayer({ + layerToShow: ShowTileInfo.styling, + features: new StaticFeatureSource(metaFeature, false), + leafletMap: options.leafletMap, + doShowLayer: options.doShowLayer + }) + + } + +} \ No newline at end of file diff --git a/UI/ShowDataLayer/TileHierarchyAggregator.ts b/UI/ShowDataLayer/TileHierarchyAggregator.ts new file mode 100644 index 000000000..4b1685981 --- /dev/null +++ b/UI/ShowDataLayer/TileHierarchyAggregator.ts @@ -0,0 +1,217 @@ +import FeatureSource, {FeatureSourceForLayer, Tiled} from "../../Logic/FeatureSource/FeatureSource"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {Tiles} from "../../Models/TileRange"; +import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; +import {BBox} from "../../Logic/BBox"; + +export class TileHierarchyAggregator implements FeatureSource { + private _parent: TileHierarchyAggregator; + private _root: TileHierarchyAggregator; + private _z: number; + private _x: number; + private _y: number; + private _tileIndex: number + private _counter: SingleTileCounter + + private _subtiles: [TileHierarchyAggregator, TileHierarchyAggregator, TileHierarchyAggregator, TileHierarchyAggregator] = [undefined, undefined, undefined, undefined] + public totalValue: number = 0 + + private static readonly empty = [] + public readonly features = new UIEventSource<{ feature: any, freshness: Date }[]>(TileHierarchyAggregator.empty) + public readonly name; + + private readonly featuresStatic = [] + private readonly featureProperties: { count: string, tileId: string, id: string }; + + private constructor(parent: TileHierarchyAggregator, z: number, x: number, y: number) { + this._parent = parent; + this._root = parent?._root ?? this + this._z = z; + this._x = x; + this._y = y; + this._tileIndex = Tiles.tile_index(z, x, y) + this.name = "Count(" + this._tileIndex + ")" + + const totals = { + id: ""+this._tileIndex, + tileId: ""+this._tileIndex, + count: ""+0 + } + this.featureProperties = totals + + const now = new Date() + const feature = { + "type": "Feature", + "properties": totals, + "geometry": { + "type": "Point", + "coordinates": Tiles.centerPointOf(z, x, y) + } + } + this.featuresStatic.push({feature: feature, freshness: now}) + + const bbox = BBox.fromTile(z, x, y) + const box = { + "type": "Feature", + "properties": totals, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [bbox.minLon, bbox.minLat], + [bbox.minLon, bbox.maxLat], + [bbox.maxLon, bbox.maxLat], + [bbox.maxLon, bbox.minLat], + [bbox.minLon, bbox.minLat] + ] + ] + } + } + this.featuresStatic.push({feature: box, freshness: now}) + } + + public getTile(tileIndex): TileHierarchyAggregator { + if (tileIndex === this._tileIndex) { + return this; + } + let [tileZ, tileX, tileY] = Tiles.tile_from_index(tileIndex) + while (tileZ - 1 > this._z) { + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + tileZ-- + } + const xDiff = tileX - (2 * this._x) + const yDiff = tileY - (2 * this._y) + const subtileIndex = yDiff * 2 + xDiff; + return this._subtiles[subtileIndex]?.getTile(tileIndex) + } + + private update() { + const newMap = new Map() + let total = 0 + this?._counter?.countsPerLayer?.data?.forEach((count, layerId) => { + newMap.set(layerId, count) + total += count + }) + + for (const tile of this._subtiles) { + if (tile === undefined) { + continue; + } + total += tile.totalValue + } + this.totalValue = total + this._parent?.update() + + if (total === 0) { + this.features.setData(TileHierarchyAggregator.empty) + } else { + this.featureProperties.count = "" + total; + this.features.data = this.featuresStatic + this.features.ping() + } + } + + public addTile(source: FeatureSourceForLayer & Tiled) { + const self = this; + if (source.tileIndex === this._tileIndex) { + if (this._counter === undefined) { + this._counter = new SingleTileCounter(this._tileIndex) + this._counter.countsPerLayer.addCallbackAndRun(_ => self.update()) + } + this._counter.addTileCount(source) + } else { + + // We have to give it to one of the subtiles + let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex) + while (tileZ - 1 > this._z) { + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + tileZ-- + } + const xDiff = tileX - (2 * this._x) + const yDiff = tileY - (2 * this._y) + + const subtileIndex = yDiff * 2 + xDiff; + if (this._subtiles[subtileIndex] === undefined) { + this._subtiles[subtileIndex] = new TileHierarchyAggregator(this, tileZ, tileX, tileY) + } + this._subtiles[subtileIndex].addTile(source) + } + + } + + public static createHierarchy() { + return new TileHierarchyAggregator(undefined, 0, 0, 0) + } + + private visitSubTiles(f : (aggr: TileHierarchyAggregator) => boolean){ + const visitFurther = f(this) + if(visitFurther){ + this._subtiles.forEach(tile => tile?.visitSubTiles(f)) + } + } + + getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number = 0) : FeatureSource{ + const self = this + + return new StaticFeatureSource( + locationControl.map(loc => { + const features = [] + const targetZoom = loc.zoom + self.visitSubTiles(aggr => { + if(aggr.totalValue < cutoff) { + return false + } + if(aggr._z === targetZoom){ + features.push(...aggr.features.data) + return false + } + return aggr._z <= targetZoom; + + }) + + return features + }) + , true); + } +} + +/** + * Keeps track of a single tile + */ +class SingleTileCounter implements Tiled { + public readonly bbox: BBox; + public readonly tileIndex: number; + public readonly countsPerLayer: UIEventSource> = new UIEventSource>(new Map()) + private readonly registeredLayers: Map = new Map(); + public readonly z: number + public readonly x: number + public readonly y: number + + + constructor(tileIndex: number) { + this.tileIndex = tileIndex + this.bbox = BBox.fromTileIndex(tileIndex) + const [z, x, y] = Tiles.tile_from_index(tileIndex) + this.z = z; + this.x = x; + this.y = y + } + + public addTileCount(source: FeatureSourceForLayer) { + const layer = source.layer.layerDef + this.registeredLayers.set(layer.id, layer) + const self = this + + source.features.map(f => { + const isDisplayed = source.layer.isDisplayed.data + self.countsPerLayer.data.set(layer.id, isDisplayed ? f.length : 0) + self.countsPerLayer.ping() + }, [source.layer.isDisplayed]) + + + } + +} \ No newline at end of file diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 7814cbbdc..5801e1d88 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -13,20 +13,19 @@ import Translations from "./i18n/Translations"; import ReviewForm from "./Reviews/ReviewForm"; import OpeningHoursVisualization from "./OpeningHours/OpeningHoursVisualization"; import State from "../State"; -import {ImageSearcher} from "../Logic/Actors/ImageSearcher"; import BaseUIElement from "./BaseUIElement"; import Title from "./Base/Title"; import Table from "./Base/Table"; import Histogram from "./BigComponents/Histogram"; import Loc from "../Models/Loc"; import {Utils} from "../Utils"; -import BaseLayer from "../Models/BaseLayer"; import LayerConfig from "../Models/ThemeConfig/LayerConfig"; import ImportButton from "./BigComponents/ImportButton"; import {Tag} from "../Logic/Tags/Tag"; import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"; import ShowDataMultiLayer from "./ShowDataLayer/ShowDataMultiLayer"; import Minimap from "./Base/Minimap"; +import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; export interface SpecialVisualization { funcName: string, @@ -67,18 +66,10 @@ export default class SpecialVisualizations { name: "image key/prefix", defaultValue: "image", 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... " - }, - { - name: "smart search", - defaultValue: "true", - doc: "Also include images given via 'Wikidata', 'wikimedia_commons' and 'mapillary" - }], + }], constr: (state: State, tags, args) => { const imagePrefix = args[0]; - const loadSpecial = args[1].toLowerCase() === "true"; - const searcher: UIEventSource<{ key: string, url: string }[]> = ImageSearcher.construct(tags, imagePrefix, loadSpecial); - - return new ImageCarousel(searcher, tags); + return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefix), tags); } }, { @@ -316,10 +307,10 @@ export default class SpecialVisualizations { const generateShareData = () => { - const title = state?.layoutToUse?.data?.title?.txt ?? "MapComplete"; + const title = state?.layoutToUse?.title?.txt ?? "MapComplete"; let matchingLayer: LayerConfig = undefined; - for (const layer of (state?.layoutToUse?.data?.layers ?? [])) { + for (const layer of (state?.layoutToUse?.layers ?? [])) { if (layer.source.osmTags.matchesProperties(tagSource?.data)) { matchingLayer = layer } @@ -337,7 +328,7 @@ export default class SpecialVisualizations { return { title: name, url: url, - text: state?.layoutToUse?.data?.shortDescription?.txt ?? "MapComplete" + text: state?.layoutToUse?.shortDescription?.txt ?? "MapComplete" } } @@ -363,15 +354,14 @@ export default class SpecialVisualizations { if (value === undefined) { return undefined } - const allUnits = [].concat(...state.layoutToUse.data.layers.map(lyr => lyr.units)) + const allUnits = [].concat(...state.layoutToUse.layers.map(lyr => lyr.units)) const unit = allUnits.filter(unit => unit.isApplicableToKey(key))[0] if (unit === undefined) { return value; } return unit.asHumanLongValue(value); - }, - [state.layoutToUse]) + }) ) } }, @@ -410,7 +400,7 @@ There are also some technicalities in your theme to keep in mind: A reference number to the original dataset is an excellen way to do this `, constr: (state, tagSource, args) => { - if (!state.layoutToUse.data.official && !state.featureSwitchIsTesting.data) { + if (!state.layoutToUse.official && !state.featureSwitchIsTesting.data) { return new Combine([new FixedUiElement("The import button is disabled for unofficial themes to prevent accidents.").SetClass("alert"), new FixedUiElement("To test, add 'test=true' to the URL. The changeset will be printed in the console. Please open a PR to officialize this theme to actually enable the import button.")]) } diff --git a/Utils.ts b/Utils.ts index 9f1373498..bd5cd62a5 100644 --- a/Utils.ts +++ b/Utils.ts @@ -10,7 +10,7 @@ export class Utils { */ public static runningFromConsole = typeof window === "undefined"; public static readonly assets_path = "./assets/svg/"; - public static externalDownloadFunction: (url: string) => Promise; + public static externalDownloadFunction: (url: string, headers?: any) => Promise; private static knownKeys = ["addExtraTags", "and", "calculatedTags", "changesetmessage", "clustering", "color", "condition", "customCss", "dashArray", "defaultBackgroundId", "description", "descriptionTail", "doNotDownload", "enableAddNewPoints", "enableBackgroundLayerSelection", "enableGeolocation", "enableLayers", "enableMoreQuests", "enableSearch", "enableShareScreen", "enableUserBadge", "freeform", "hideFromOverview", "hideInAnswer", "icon", "iconOverlays", "iconSize", "id", "if", "ifnot", "isShown", "key", "language", "layers", "lockLocation", "maintainer", "mappings", "maxzoom", "maxZoom", "minNeededElements", "minzoom", "multiAnswer", "name", "or", "osmTags", "passAllFeatures", "presets", "question", "render", "roaming", "roamingRenderings", "rotation", "shortDescription", "socialImage", "source", "startLat", "startLon", "startZoom", "tagRenderings", "tags", "then", "title", "titleIcons", "type", "version", "wayHandling", "widenFactor", "width"] private static extraKeys = ["nl", "en", "fr", "de", "pt", "es", "name", "phone", "email", "amenity", "leisure", "highway", "building", "yes", "no", "true", "false"] @@ -192,11 +192,12 @@ export class Utils { } /** - * Copies all key-value pairs of the source into the target. + * Copies all key-value pairs of the source into the target. This will change the target * If the key starts with a '+', the values of the list will be appended to the target instead of overwritten * @param source * @param target * @constructor + * @return the second parameter as is */ static Merge(source: any, target: any) { for (const key in source) { @@ -247,64 +248,6 @@ export class Utils { return dict.get(k); } - /** - * Calculates the tile bounds of the - * @param z - * @param x - * @param y - * @returns [[maxlat, minlon], [minlat, maxlon]] - */ - static tile_bounds(z: number, x: number, y: number): [[number, number], [number, number]] { - return [[Utils.tile2lat(y, z), Utils.tile2long(x, z)], [Utils.tile2lat(y + 1, z), Utils.tile2long(x + 1, z)]] - } - - static tile_bounds_lon_lat(z: number, x: number, y: number): [[number, number], [number, number]] { - return [[Utils.tile2long(x, z), Utils.tile2lat(y, z)], [Utils.tile2long(x + 1, z), Utils.tile2lat(y + 1, z)]] - } - - static tile_index(z: number, x: number, y: number): number { - return ((x * (2 << z)) + y) * 100 + z - } - - /** - * Given a tile index number, returns [z, x, y] - * @param index - * @returns 'zxy' - */ - static tile_from_index(index: number): [number, number, number] { - const z = index % 100; - const factor = 2 << z - index = Math.floor(index / 100) - return [z, Math.floor(index / factor), index % factor] - } - - /** - * Return x, y of the tile containing (lat, lon) on the given zoom level - */ - static embedded_tile(lat: number, lon: number, z: number): { x: number, y: number, z: number } { - return {x: Utils.lon2tile(lon, z), y: Utils.lat2tile(lat, z), z: z} - } - - static TileRangeBetween(zoomlevel: number, lat0: number, lon0: number, lat1: number, lon1: number): TileRange { - const t0 = Utils.embedded_tile(lat0, lon0, zoomlevel) - const t1 = Utils.embedded_tile(lat1, lon1, zoomlevel) - - const xstart = Math.min(t0.x, t1.x) - const xend = Math.max(t0.x, t1.x) - const ystart = Math.min(t0.y, t1.y) - const yend = Math.max(t0.y, t1.y) - const total = (1 + xend - xstart) * (1 + yend - ystart) - - return { - xstart: xstart, - xend: xend, - ystart: ystart, - yend: yend, - total: total, - zoomlevel: zoomlevel - } - } - public static MinifyJSON(stringified: string): string { stringified = stringified.replace(/\|/g, "||"); @@ -345,16 +288,6 @@ export class Utils { return result; } - public static MapRange(tileRange: TileRange, f: (x: number, y: number) => T): T[] { - const result: T[] = [] - for (let x = tileRange.xstart; x <= tileRange.xend; x++) { - for (let y = tileRange.ystart; y <= tileRange.yend; y++) { - const t = f(x, y); - result.push(t) - } - } - return result; - } private static injectedDownloads = {} @@ -362,39 +295,51 @@ export class Utils { Utils.injectedDownloads[url] = data } - public static downloadJson(url: string): Promise { - - const injected = Utils.injectedDownloads[url] - if (injected !== undefined) { - console.log("Using injected resource for test for URL", url) - return new Promise((resolve, _) => resolve(injected)) - } - + public static download(url: string, headers?: any): Promise { if (this.externalDownloadFunction !== undefined) { - return this.externalDownloadFunction(url) + return this.externalDownloadFunction(url, headers) } return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = () => { if (xhr.status == 200) { - try { - console.log("Got a response! Parsing now...") - resolve(JSON.parse(xhr.response)) - } catch (e) { - reject("Not a valid json: " + xhr.response) - } + resolve(xhr.response) + } else if (xhr.status === 509 || xhr.status === 429) { + reject("rate limited") } else { reject(xhr.statusText) } }; xhr.open('GET', url); - xhr.setRequestHeader("accept", "application/json") + if (headers !== undefined) { + + for (const key in headers) { + xhr.setRequestHeader(key, headers[key]) + } + } + xhr.send(); + xhr.onerror = reject } ) } + public static async downloadJson(url: string, headers?: any): Promise { + const injected = Utils.injectedDownloads[url] + if (injected !== undefined) { + console.log("Using injected resource for test for URL", url) + return new Promise((resolve, _) => resolve(injected)) + } + const data = await Utils.download(url, Utils.Merge({"accept": "application/json"}, headers ?? {})) + try { + return JSON.parse(data) + } catch (e) { + console.error("Could not parse ", data, "due to", e, "\n", e.stack) + throw e; + } + } + /** * Triggers a 'download file' popup which will download the contents */ @@ -449,22 +394,6 @@ export class Utils { return bestColor ?? hex; } - private static tile2long(x, z) { - return (x / Math.pow(2, z) * 360 - 180); - } - - private static tile2lat(y, z) { - const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z); - return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); - } - - private static lon2tile(lon, zoom) { - return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom))); - } - - private static lat2tile(lat, zoom) { - return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom))); - } 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); @@ -506,5 +435,11 @@ export class Utils { } return copy } + + public static async waitFor(timeMillis: number): Promise { + return new Promise((resolve) => { + window.setTimeout(resolve, timeMillis); + }) + } } diff --git a/assets/layers/barrier/barrier.json b/assets/layers/barrier/barrier.json index e7cc75562..f06b8e237 100644 --- a/assets/layers/barrier/barrier.json +++ b/assets/layers/barrier/barrier.json @@ -1,293 +1,293 @@ { - "id": "barrier", - "name": { - "en": "Barriers", - "nl": "Barrières" - }, - "description": { - "en": "Obstacles while cycling, such as bollards and cycle barriers", - "nl": "Hindernissen tijdens het fietsen, zoals paaltjes en fietshekjes" - }, - "source": { - "osmTags": { - "or": [ - "barrier=bollard", - "barrier=cycle_barrier" - ] - } - }, - "minzoom": 17, - "title": { - "render": { - "en": "Barrier", - "nl": "Barrière" + "id": "barrier", + "name": { + "en": "Barriers", + "nl": "Barrières" }, - "mappings": [ - { - "if": "barrier=bollard", - "then": { - "en": "Bollard", - "nl": "Paaltje" + "description": { + "en": "Obstacles while cycling, such as bollards and cycle barriers", + "nl": "Hindernissen tijdens het fietsen, zoals paaltjes en fietshekjes" + }, + "source": { + "osmTags": { + "or": [ + "barrier=bollard", + "barrier=cycle_barrier" + ] } - }, - { - "if": "barrier=cycle_barrier", - "then": { - "en": "Cycling Barrier", - "nl": "Fietshekjes" + }, + "minzoom": 17, + "title": { + "render": { + "en": "Barrier", + "nl": "Barrière" + }, + "mappings": [ + { + "if": "barrier=bollard", + "then": { + "en": "Bollard", + "nl": "Paaltje" + } + }, + { + "if": "barrier=cycle_barrier", + "then": { + "en": "Cycling Barrier", + "nl": "Fietshekjes" + } + } + ] + }, + "icon": "./assets/layers/barrier/barrier.svg", + "width": "5", + "presets": [ + { + "title": { + "en": "Bollard", + "nl": "Paaltje" + }, + "tags": [ + "barrier=bollard" + ], + "description": { + "en": "A bollard in the road", + "nl": "Een paaltje in de weg" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } + }, + { + "title": { + "en": "Cycle barrier", + "nl": "Fietshekjes" + }, + "tags": [ + "barrier=bollard" + ], + "description": { + "en": "Cycle barrier, slowing down cyclists", + "nl": "Fietshekjes, voor het afremmen van fietsers" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } + } + ], + "tagRenderings": [ + { + "question": { + "en": "Can a bicycle go past this barrier?", + "nl": "Kan een fietser langs deze barrière?" + }, + "mappings": [ + { + "if": "bicycle=yes", + "then": { + "en": "A cyclist can go past this.", + "nl": "Een fietser kan hier langs." + } + }, + { + "if": "bicycle=no", + "then": { + "en": "A cyclist can not go past this.", + "nl": "Een fietser kan hier niet langs." + } + } + ], + "id": "bicycle=yes/no" + }, + { + "question": { + "en": "What kind of bollard is this?", + "nl": "Wat voor soort paal is dit?" + }, + "condition": "barrier=bollard", + "mappings": [ + { + "if": "bollard=removable", + "then": { + "en": "Removable bollard", + "nl": "Verwijderbare paal" + } + }, + { + "if": "bollard=fixed", + "then": { + "en": "Fixed bollard", + "nl": "Vaste paal" + } + }, + { + "if": "bollard=foldable", + "then": { + "en": "Bollard that can be folded down", + "nl": "Paal die platgevouwen kan worden" + } + }, + { + "if": "bollard=flexible", + "then": { + "en": "Flexible bollard, usually plastic", + "nl": "Flexibele paal, meestal plastic" + } + }, + { + "if": "bollard=rising", + "then": { + "en": "Rising bollard", + "nl": "Verzonken poller" + } + } + ], + "id": "Bollard type" + }, + { + "question": { + "en": "What kind of cycling barrier is this?", + "nl": "Wat voor fietshekjes zijn dit?" + }, + "condition": "barrier=cycle_barrier", + "mappings": [ + { + "if": "cycle_barrier:type=single", + "then": { + "en": "Single, just two barriers with a space inbetween ", + "nl": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " + } + }, + { + "if": "cycle_barrier:type=double", + "then": { + "en": "Double, two barriers behind each other ", + "nl": "Dubbel, twee hekjes achter elkaar " + } + }, + { + "if": "cycle_barrier:type=triple", + "then": { + "en": "Triple, three barriers behind each other ", + "nl": "Drievoudig, drie hekjes achter elkaar " + } + }, + { + "if": "cycle_barrier:type=squeeze", + "then": { + "en": "Squeeze gate, gap is smaller at top, than at the bottom ", + "nl": "Knijppoort, ruimte is smaller aan de top, dan aan de bodem " + } + } + ], + "id": "Cycle barrier type" + }, + { + "render": { + "en": "Maximum width: {maxwidth:physical} m", + "nl": "Maximumbreedte: {maxwidth:physical} m" + }, + "question": { + "en": "How wide is the gap left over besides the barrier?", + "nl": "Hoe breed is de ruimte naast de barrière?" + }, + "condition": { + "and": [ + "cycle_barrier:type!=double", + "cycle_barrier:type!=triple" + ] + }, + "freeform": { + "key": "maxwidth:physical", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + }, + "id": "MaxWidth" + }, + { + "render": { + "en": "Space between barriers (along the length of the road): {width:separation} m", + "nl": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" + }, + "question": { + "en": "How much space is there between the barriers (along the length of the road)?", + "nl": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "width:separation", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + }, + "id": "Space between barrier (cyclebarrier)" + }, + { + "render": { + "en": "Width of opening: {width:opening} m", + "nl": "Breedte van de opening: {width:opening} m" + }, + "question": { + "en": "How wide is the smallest opening next to the barriers?", + "nl": "Hoe breed is de smalste opening naast de barrières?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "width:opening", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + }, + "id": "Width of opening (cyclebarrier)" + }, + { + "render": { + "en": "Overlap: {overlap} m" + }, + "question": { + "en": "How much overlap do the barriers have?", + "nl": "Hoeveel overlappen de barrières?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "overlap", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + }, + "id": "Overlap (cyclebarrier)" } - } ] - }, - "icon": "./assets/layers/barrier/barrier.svg", - "width": "5", - "presets": [ - { - "title": { - "en": "Bollard", - "nl": "Paaltje" - }, - "tags": [ - "barrier=bollard" - ], - "description": { - "en": "A bollard in the road", - "nl": "Een paaltje in de weg" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - }, - { - "title": { - "en": "Cycle barrier", - "nl": "Fietshekjes" - }, - "tags": [ - "barrier=bollard" - ], - "description": { - "en": "Cycle barrier, slowing down cyclists", - "nl": "Fietshekjes, voor het afremmen van fietsers" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - } - ], - "tagRenderings": [ - { - "#": "bicycle=yes/no", - "question": { - "en": "Can a bicycle go past this barrier?", - "nl": "Kan een fietser langs deze barrière?" - }, - "mappings": [ - { - "if": "bicycle=yes", - "then": { - "en": "A cyclist can go past this.", - "nl": "Een fietser kan hier langs." - } - }, - { - "if": "bicycle=no", - "then": { - "en": "A cyclist can not go past this.", - "nl": "Een fietser kan hier niet langs." - } - } - ] - }, - { - "#": "Bollard type", - "question": { - "en": "What kind of bollard is this?", - "nl": "Wat voor soort paal is dit?" - }, - "condition": "barrier=bollard", - "mappings": [ - { - "if": "bollard=removable", - "then": { - "en": "Removable bollard", - "nl": "Verwijderbare paal" - } - }, - { - "if": "bollard=fixed", - "then": { - "en": "Fixed bollard", - "nl": "Vaste paal" - } - }, - { - "if": "bollard=foldable", - "then": { - "en": "Bollard that can be folded down", - "nl": "Paal die platgevouwen kan worden" - } - }, - { - "if": "bollard=flexible", - "then": { - "en": "Flexible bollard, usually plastic", - "nl": "Flexibele paal, meestal plastic" - } - }, - { - "if": "bollard=rising", - "then": { - "en": "Rising bollard", - "nl": "Verzonken poller" - } - } - ] - }, - { - "#": "Cycle barrier type", - "question": { - "en": "What kind of cycling barrier is this?", - "nl": "Wat voor fietshekjes zijn dit?" - }, - "condition": "barrier=cycle_barrier", - "mappings": [ - { - "if": "cycle_barrier:type=single", - "then": { - "en": "Single, just two barriers with a space inbetween ", - "nl": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " - } - }, - { - "if": "cycle_barrier:type=double", - "then": { - "en": "Double, two barriers behind each other ", - "nl": "Dubbel, twee hekjes achter elkaar " - } - }, - { - "if": "cycle_barrier:type=triple", - "then": { - "en": "Triple, three barriers behind each other ", - "nl": "Drievoudig, drie hekjes achter elkaar " - } - }, - { - "if": "cycle_barrier:type=squeeze", - "then": { - "en": "Squeeze gate, gap is smaller at top, than at the bottom ", - "nl": "Knijppoort, ruimte is smaller aan de top, dan aan de bodem " - } - } - ] - }, - { - "#": "MaxWidth", - "render": { - "en": "Maximum width: {maxwidth:physical} m", - "nl": "Maximumbreedte: {maxwidth:physical} m" - }, - "question": { - "en": "How wide is the gap left over besides the barrier?", - "nl": "Hoe breed is de ruimte naast de barrière?" - }, - "condition": { - "and": [ - "cycle_barrier:type!=double", - "cycle_barrier:type!=triple" - ] - }, - "freeform": { - "key": "maxwidth:physical", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - } - }, - { - "#": "Space between barrier (cyclebarrier)", - "render": { - "en": "Space between barriers (along the length of the road): {width:separation} m", - "nl": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" - }, - "question": { - "en": "How much space is there between the barriers (along the length of the road)?", - "nl": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "width:separation", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - }, - { - "#": "Width of opening (cyclebarrier)", - "render": { - "en": "Width of opening: {width:opening} m", - "nl": "Breedte van de opening: {width:opening} m" - }, - "question": { - "en": "How wide is the smallest opening next to the barriers?", - "nl": "Hoe breed is de smalste opening naast de barrières?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "width:opening", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - }, - { - "#": "Overlap (cyclebarrier)", - "render": { - "en": "Overlap: {overlap} m" - }, - "question": { - "en": "How much overlap do the barriers have?", - "nl": "Hoeveel overlappen de barrières?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "overlap", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - } - ] } \ No newline at end of file diff --git a/assets/layers/bench/bench.json b/assets/layers/bench/bench.json index 7f2c93fcf..af5bbd10b 100644 --- a/assets/layers/bench/bench.json +++ b/assets/layers/bench/bench.json @@ -1,614 +1,604 @@ { - "id": "bench", - "name": { - "en": "Benches", - "de": "Sitzbänke", - "fr": "Bancs", - "nl": "Zitbanken", - "es": "Bancos", - "hu": "Padok", - "id": "Bangku", - "it": "Panchine", - "ru": "Скамейки", - "zh_Hans": "长椅", - "zh_Hant": "長椅", - "nb_NO": "Benker", - "fi": "Penkit", - "pl": "Ławki", - "pt_BR": "Bancos" - }, - "minzoom": 17, - "source": { - "osmTags": "amenity=bench" - }, - "wayHandling": 1, - "title": { - "render": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "hu": "Pad", - "id": "Bangku", - "it": "Panchina", - "ru": "Скамейка", - "zh_Hans": "长椅", - "zh_Hant": "長椅", - "nb_NO": "Benk", - "fi": "Penkki", - "pl": "Ławka", - "pt_BR": "Banco" - } - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "Backrest", - "de": "Rückenlehne", - "fr": "Dossier", - "nl": "Rugleuning", - "es": "Respaldo", - "hu": "Háttámla", - "id": "Sandaran", - "it": "Schienale", - "ru": "Спинка", - "zh_Hans": "靠背", - "zh_Hant": "靠背", - "nb_NO": "Rygglene", - "fi": "Selkänoja", - "pl": "Oparcie", - "pt_BR": "Encosto" - }, - "freeform": { - "key": "backrest" - }, - "mappings": [ - { - "if": "backrest=yes", - "then": { - "en": "Backrest: Yes", - "de": "Rückenlehne: Ja", - "fr": "Dossier : Oui", - "nl": "Heeft een rugleuning", - "es": "Respaldo: Si", - "hu": "Háttámla: Igen", - "id": "Sandaran: Ya", - "it": "Schienale: Sì", - "ru": "Со спинкой", - "zh_Hans": "靠背:有", - "zh_Hant": "靠背:有", - "nb_NO": "Rygglene: Ja", - "fi": "Selkänoja: kyllä", - "pl": "Oparcie: Tak", - "pt_BR": "Encosto: Sim" - } - }, - { - "if": "backrest=no", - "then": { - "en": "Backrest: No", - "de": "Rückenlehne: Nein", - "fr": "Dossier : Non", - "nl": "Rugleuning ontbreekt", - "es": "Respaldo: No", - "hu": "Háttámla: Nem", - "id": "Sandaran: Tidak", - "it": "Schienale: No", - "ru": "Без спинки", - "zh_Hans": "靠背:无", - "zh_Hant": "靠背:無", - "nb_NO": "Rygglene: Nei", - "fi": "Selkänoja: ei", - "pl": "Oparcie: Nie", - "pt_BR": "Encosto: Não" - } - } - ], - "question": { - "en": "Does this bench have a backrest?", - "de": "Hat diese Bank eine Rückenlehne?", - "fr": "Ce banc dispose-t-il d'un dossier ?", - "nl": "Heeft deze zitbank een rugleuning?", - "es": "¿Este banco tiene un respaldo?", - "hu": "Van háttámlája ennek a padnak?", - "id": "Apakah bangku ini memiliki sandaran?", - "it": "Questa panchina ha lo schienale?", - "ru": "Есть ли у этой скамейки спинка?", - "zh_Hans": "这个长椅有靠背吗?", - "zh_Hant": "這個長椅是否有靠背?", - "nb_NO": "Har denne beken et rygglene?", - "pl": "Czy ta ławka ma oparcie?", - "pt_BR": "Este assento tem um escosto?" - } - }, - { - "render": { - "en": "{seats} seats", - "de": "{seats} Sitzplätze", - "fr": "{seats} places", - "nl": "{seats} zitplaatsen", - "es": "{seats} asientos", - "hu": "{seats} ülőhely", - "id": "{seats} kursi", - "it": "{seats} posti", - "ru": "{seats} мест", - "zh_Hant": "{seats} 座位數", - "nb_NO": "{seats} seter", - "pl": "{seats} siedzeń", - "pt_BR": "{seats} assentos" - }, - "freeform": { - "key": "seats", - "type": "nat" - }, - "question": { - "en": "How many seats does this bench have?", - "de": "Wie viele Sitzplätze hat diese Bank?", - "fr": "De combien de places dispose ce banc ?", - "nl": "Hoeveel zitplaatsen heeft deze bank?", - "es": "¿Cuántos asientos tiene este banco?", - "hu": "Hány ülőhely van ezen a padon?", - "it": "Quanti posti ha questa panchina?", - "ru": "Сколько мест на этой скамейке?", - "zh_Hans": "这个长椅有几个座位?", - "zh_Hant": "這個長椅有幾個位子?", - "nb_NO": "Hvor mange sitteplasser har denne benken?", - "pl": "Ile siedzeń ma ta ławka?", - "pt_BR": "Quantos assentos este banco tem?" - } - }, - { - "render": { - "en": "Material: {material}", - "de": "Material: {material}", - "fr": "Matériau : {material}", - "nl": "Gemaakt van {material}", - "es": "Material: {material}", - "hu": "Anyag: {material}", - "it": "Materiale: {material}", - "ru": "Материал: {material}", - "zh_Hanå¨s": "材质: {material}", - "zh_Hant": "材質:{material}", - "nb_NO": "Materiale: {material}", - "fi": "Materiaali: {material}", - "zh_Hans": "材质: {material}", - "pl": "Materiał: {material}", - "pt_BR": "Material: {material}" - }, - "freeform": { - "key": "material", - "addExtraTags": [] - }, - "mappings": [ - { - "if": "material=wood", - "then": { - "en": "Material: wood", - "de": "Material: Holz", - "fr": "Matériau : bois", - "nl": "Gemaakt uit hout", - "es": "Material: madera", - "hu": "Anyag: fa", - "it": "Materiale: legno", - "ru": "Материал: дерево", - "zh_Hans": "材质:木", - "nb_NO": "Materiale: tre", - "zh_Hant": "材質:木頭", - "pt_BR": "Material: madeira", - "fi": "Materiaali: puu", - "pl": "Materiał: drewno" - } - }, - { - "if": "material=metal", - "then": { - "en": "Material: metal", - "de": "Material: Metall", - "fr": "Matériau : métal", - "nl": "Gemaakt uit metaal", - "es": "Material: metal", - "hu": "Anyag: fém", - "it": "Materiale: metallo", - "ru": "Материал: металл", - "zh_Hans": "材质:金属", - "nb_NO": "Materiale: metall", - "zh_Hant": "材質:金屬", - "pl": "Materiał: metal", - "pt_BR": "Material: metal" - } - }, - { - "if": "material=stone", - "then": { - "en": "Material: stone", - "de": "Material: Stein", - "fr": "Matériau : pierre", - "nl": "Gemaakt uit steen", - "es": "Material: piedra", - "hu": "Anyag: kő", - "it": "Materiale: pietra", - "ru": "Материал: камень", - "zh_Hans": "材质:石头", - "nb_NO": "Materiale: stein", - "zh_Hant": "材質:石頭", - "pt_BR": "Material: pedra", - "fi": "Materiaali: kivi", - "pl": "Materiał: kamień" - } - }, - { - "if": "material=concrete", - "then": { - "en": "Material: concrete", - "de": "Material: Beton", - "fr": "Matériau : béton", - "nl": "Gemaakt uit beton", - "es": "Material: concreto", - "hu": "Anyag: beton", - "it": "Materiale: cemento", - "ru": "Материал: бетон", - "zh_Hans": "材质:混凝土", - "nb_NO": "Materiale: betong", - "zh_Hant": "材質:水泥", - "pt_BR": "Material: concreto", - "fi": "Materiaali: betoni", - "pl": "Materiał: beton" - } - }, - { - "if": "material=plastic", - "then": { - "en": "Material: plastic", - "de": "Material: Kunststoff", - "fr": "Matériau : plastique", - "nl": "Gemaakt uit plastiek", - "es": "Material: plastico", - "hu": "Anyag: műanyag", - "it": "Materiale: plastica", - "ru": "Материал: пластик", - "zh_Hans": "材质:塑料", - "nb_NO": "Materiale: plastikk", - "zh_Hant": "材質:塑膠", - "pt_BR": "Material: plástico", - "fi": "Materiaali: muovi", - "pl": "Materiał: plastik" - } - }, - { - "if": "material=steel", - "then": { - "en": "Material: steel", - "de": "Material: Stahl", - "fr": "Matériau : acier", - "nl": "Gemaakt uit staal", - "es": "Material: acero", - "hu": "Anyag: acél", - "it": "Materiale: acciaio", - "ru": "Материал: сталь", - "zh_Hans": "材质:不锈钢", - "nb_NO": "Materiale: stål", - "zh_Hant": "材質:鋼鐵", - "pt_BR": "Material: aço", - "fi": "Materiaali: teräs", - "pl": "Materiał: stal" - } - } - ], - "question": { - "en": "What is the bench (seating) made from?", - "de": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", - "fr": "De quel matériau ce banc est-il fait ?", - "nl": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", - "hu": "Miből van a pad (ülő része)?", - "it": "Di che materiale è fatta questa panchina?", - "zh_Hans": "这个长椅(或座椅)是用什么材料做的?", - "ru": "Из какого материала сделана скамейка?", - "zh_Hant": "這個長椅 (座位) 是什麼做的?", - "pt_BR": "De que é feito o banco (assento)?", - "pl": "Z czego wykonana jest ławka (siedzisko)?" - } - }, - { - "question": { - "en": "In which direction are you looking when sitting on the bench?", - "de": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", - "nl": "In welke richting kijk je wanneer je op deze zitbank zit?", - "fr": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", - "hu": "Milyen irányba néz a pad?", - "it": "In che direzione si guarda quando si è seduti su questa panchina?", - "ru": "В каком направлении вы смотрите, когда сидите на скамейке?", - "zh_Hans": "坐在长椅上的时候你目视的方向是哪边?", - "zh_Hant": "坐在長椅時是面對那個方向?", - "pt_BR": "Em que direção você olha quando está sentado no banco?", - "pl": "W jakim kierunku patrzysz siedząc na ławce?" - }, - "render": { - "en": "When sitting on the bench, one looks towards {direction}°.", - "de": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°.", - "nl": "Wanneer je op deze bank zit, dan kijk je in {direction}°.", - "fr": "Assis sur le banc, on regarde vers {direction}°.", - "hu": "A pad {direction}° felé néz.", - "it": "Quando si è seduti su questa panchina, si guarda verso {direction}°.", - "zh_Hans": "坐在长椅上的时候目视方向为 {direction}°方位。", - "ru": "Сидя на скамейке, вы смотрите в сторону {direction}°.", - "zh_Hant": "當坐在長椅時,那個人朝向 {direction}°。", - "pl": "Siedząc na ławce, patrzy się w kierunku {direction}°.", - "pt_BR": "Ao sentar-se no banco, olha-se para {direction} °." - }, - "freeform": { - "key": "direction", - "type": "direction" - } - }, - { - "render": { - "en": "Colour: {colour}", - "de": "Farbe: {colour}", - "fr": "Couleur : {colour}", - "nl": "Kleur: {colour}", - "hu": "Szín: {colour}", - "it": "Colore: {colour}", - "ru": "Цвет: {colour}", - "id": "Warna: {colour}", - "zh_Hans": "颜色: {colour}", - "zh_Hant": "顏色:{colour}", - "nb_NO": "Farge: {colour}", - "pt_BR": "Cor: {colour}", - "fi": "Väri: {colour}", - "pl": "Kolor: {colour}" - }, - "question": { - "en": "Which colour does this bench have?", - "de": "Welche Farbe hat diese Sitzbank?", - "fr": "Quelle est la couleur de ce banc ?", - "nl": "Welke kleur heeft deze zitbank?", - "hu": "Milyen színű a pad?", - "it": "Di che colore è questa panchina?", - "ru": "Какого цвета скамейка?", - "zh_Hans": "这个长椅是什么颜色的?", - "zh_Hant": "這個長椅是什麼顏色的?", - "pt_BR": "Qual a cor dessa bancada?", - "pl": "Jaki kolor ma ta ławka?" - }, - "freeform": { - "key": "colour", - "type": "color" - }, - "mappings": [ - { - "if": "colour=brown", - "then": { - "en": "Colour: brown", - "de": "Farbe: braun", - "fr": "Couleur : marron", - "nl": "De kleur is bruin", - "hu": "Szín: barna", - "it": "Colore: marrone", - "ru": "Цвет: коричневый", - "zh_Hans": "颜色:棕", - "zh_Hant": "顏色:棕色", - "nb_NO": "Farge: brun", - "pt_BR": "Cor: marrom", - "fi": "Väri: ruskea", - "pl": "Kolor: brązowy" - } - }, - { - "if": "colour=green", - "then": { - "en": "Colour: green", - "de": "Farbe: grün", - "fr": "Couleur : verte", - "nl": "De kleur is groen", - "hu": "Szín: zöld", - "it": "Colore: verde", - "ru": "Цвет: зеленый", - "zh_Hans": "颜色:绿", - "zh_Hant": "顏色:綠色", - "nb_NO": "Farge: grønn", - "pt_BR": "Cor: verde", - "fi": "Väri: vihreä", - "pl": "Kolor: zielony" - } - }, - { - "if": "colour=gray", - "then": { - "en": "Colour: gray", - "de": "Farbe: grau", - "fr": "Couleur : gris", - "nl": "De kleur is grijs", - "hu": "Szín: szürke", - "it": "Colore: grigio", - "ru": "Цвет: серый", - "zh_Hans": "颜色:灰", - "zh_Hant": "顏色:灰色", - "nb_NO": "Farge: grå", - "pt_BR": "Cor: cinza", - "fi": "Väri: harmaa", - "pl": "Kolor: szary" - } - }, - { - "if": "colour=white", - "then": { - "en": "Colour: white", - "de": "Farbe: weiß", - "fr": "Couleur : blanc", - "nl": "De kleur is wit", - "hu": "Szín: fehér", - "it": "Colore: bianco", - "ru": "Цвет: белый", - "zh_Hans": "颜色:白", - "zh_Hant": "顏色:白色", - "nb_NO": "Farge: hvit", - "pt_BR": "Cor: branco", - "fi": "Väri: valkoinen", - "pl": "Kolor: biały" - } - }, - { - "if": "colour=red", - "then": { - "en": "Colour: red", - "de": "Farbe: rot", - "fr": "Couleur : rouge", - "nl": "De kleur is rood", - "hu": "Szín: piros", - "it": "Colore: rosso", - "ru": "Цвет: красный", - "zh_Hans": "颜色:红", - "zh_Hant": "顏色:紅色", - "nb_NO": "Farge: rød", - "pt_BR": "Cor: vermelho", - "fi": "Väri: punainen", - "pl": "Kolor: czerwony" - } - }, - { - "if": "colour=black", - "then": { - "en": "Colour: black", - "de": "Farbe: schwarz", - "fr": "Couleur : noire", - "nl": "De kleur is zwart", - "hu": "Szín: fekete", - "it": "Colore: nero", - "ru": "Цвет: чёрный", - "zh_Hans": "颜色:黑", - "zh_Hant": "顏色:黑色", - "nb_NO": "Farge: svart", - "pt_BR": "Cor: preto", - "fi": "Väri: musta", - "pl": "Kolor: czarny" - } - }, - { - "if": "colour=blue", - "then": { - "en": "Colour: blue", - "de": "Farbe: blau", - "fr": "Couleur : bleu", - "nl": "De kleur is blauw", - "hu": "Szín: kék", - "it": "Colore: blu", - "ru": "Цвет: синий", - "zh_Hans": "颜色:蓝", - "zh_Hant": "顏色:藍色", - "nb_NO": "Farge: blå", - "pt_BR": "Cor: azul", - "fi": "Väri: sininen", - "pl": "Kolor: niebieski" - } - }, - { - "if": "colour=yellow", - "then": { - "en": "Colour: yellow", - "de": "Farbe: gelb", - "fr": "Couleur : jaune", - "nl": "De kleur is geel", - "hu": "Szín: sárga", - "it": "Colore: giallo", - "ru": "Цвет: желтый", - "zh_Hans": "颜色:黄", - "zh_Hant": "顏色:黃色", - "nb_NO": "Farge: gul", - "pt_BR": "Cor: amarelo", - "fi": "Väri: keltainen", - "pl": "Kolor: żółty" - } - } - ] - }, - { - "question": { - "en": "When was this bench last surveyed?", - "nl": "Wanneer is deze laatste bank laatst gesurveyed?", - "fr": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", - "it": "Quando è stata verificata l’ultima volta questa panchina?", - "zh_Hans": "上次对这个长椅实地调查是什么时候?", - "de": "Wann wurde diese Bank zuletzt überprüft?", - "ru": "Когда последний раз обследовали эту скамейку?", - "zh_Hant": "上一次探察長椅是什麼時候?", - "pt_BR": "Quando esta bancada foi pesquisada pela última vez?", - "pl": "Kiedy ostatnio badano tę ławkę?" - }, - "render": { - "en": "This bench was last surveyed on {survey:date}", - "nl": "Deze bank is laatst gesurveyd op {survey:date}", - "fr": "Ce banc a été contrôlé pour la dernière fois le {survey:date}", - "it": "Questa panchina è stata controllata l’ultima volta in data {survey:date}", - "zh_Hans": "这个长椅于 {survey:date}最后一次实地调查", - "de": "Diese Bank wurde zuletzt überprüft am {survey:date}", - "ru": "Последний раз обследование этой скамейки проводилось {survey:date}", - "zh_Hant": "這個長椅最後是在 {survey:date} 探查的", - "pt_BR": "Esta bancada foi pesquisada pela última vez em {survey:date}", - "pl": "Ławka ta była ostatnio badana w dniu {survey:date}" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": "Surveyed today!" - } - ] - } - ], - "icon": { - "render": "circle:#FE6F32;./assets/layers/bench/bench.svg" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=bench" - ], - "title": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "it": "Panchina", - "ru": "Скамейка", + "id": "bench", + "name": { + "en": "Benches", + "de": "Sitzbänke", + "fr": "Bancs", + "nl": "Zitbanken", + "es": "Bancos", + "hu": "Padok", "id": "Bangku", + "it": "Panchine", + "ru": "Скамейки", "zh_Hans": "长椅", - "nb_NO": "Benk", "zh_Hant": "長椅", - "pt_BR": "Banco", - "fi": "Penkki", - "pl": "Ławka" - }, - "description": { - "en": "Add a new bench", - "de": "Neue Sitzbank eintragen", - "fr": "Ajouter un nouveau banc", - "nl": "Voeg een nieuwe zitbank toe", - "es": "Añadir un nuevo banco", - "hu": "Pad hozzáadása", - "it": "Aggiungi una nuova panchina", - "ru": "Добавить новую скамейку", - "zh_Hans": "增加一个新的长椅", - "nb_NO": "Legg til en ny benk", - "zh_Hant": "新增長椅", - "pt_BR": "Adicionar um novo banco", - "fi": "Lisää uusi penkki", - "pl": "Dodaj nową ławkę" - }, - "preciseInput": { - "preferredBackground": "photo" - } - } - ] + "nb_NO": "Benker", + "fi": "Penkit", + "pl": "Ławki", + "pt_BR": "Bancos" + }, + "minzoom": 17, + "source": { + "osmTags": "amenity=bench" + }, + "wayHandling": 1, + "title": { + "render": { + "en": "Bench", + "de": "Sitzbank", + "fr": "Banc", + "nl": "Zitbank", + "es": "Banco", + "hu": "Pad", + "id": "Bangku", + "it": "Panchina", + "ru": "Скамейка", + "zh_Hans": "长椅", + "zh_Hant": "長椅", + "nb_NO": "Benk", + "fi": "Penkki", + "pl": "Ławka", + "pt_BR": "Banco" + } + }, + "tagRenderings": [ + "images", + { + "render": { + "en": "Backrest", + "de": "Rückenlehne", + "fr": "Dossier", + "nl": "Rugleuning", + "es": "Respaldo", + "hu": "Háttámla", + "id": "Sandaran", + "it": "Schienale", + "ru": "Спинка", + "zh_Hans": "靠背", + "zh_Hant": "靠背", + "nb_NO": "Rygglene", + "fi": "Selkänoja", + "pl": "Oparcie", + "pt_BR": "Encosto" + }, + "freeform": { + "key": "backrest" + }, + "mappings": [ + { + "if": "backrest=yes", + "then": { + "en": "Backrest: Yes", + "de": "Rückenlehne: Ja", + "fr": "Dossier : Oui", + "nl": "Heeft een rugleuning", + "es": "Respaldo: Si", + "hu": "Háttámla: Igen", + "id": "Sandaran: Ya", + "it": "Schienale: Sì", + "ru": "Со спинкой", + "zh_Hans": "靠背:有", + "zh_Hant": "靠背:有", + "nb_NO": "Rygglene: Ja", + "fi": "Selkänoja: kyllä", + "pl": "Oparcie: Tak", + "pt_BR": "Encosto: Sim" + } + }, + { + "if": "backrest=no", + "then": { + "en": "Backrest: No", + "de": "Rückenlehne: Nein", + "fr": "Dossier : Non", + "nl": "Rugleuning ontbreekt", + "es": "Respaldo: No", + "hu": "Háttámla: Nem", + "id": "Sandaran: Tidak", + "it": "Schienale: No", + "ru": "Без спинки", + "zh_Hans": "靠背:无", + "zh_Hant": "靠背:無", + "nb_NO": "Rygglene: Nei", + "fi": "Selkänoja: ei", + "pl": "Oparcie: Nie", + "pt_BR": "Encosto: Não" + } + } + ], + "question": { + "en": "Does this bench have a backrest?", + "de": "Hat diese Bank eine Rückenlehne?", + "fr": "Ce banc dispose-t-il d'un dossier ?", + "nl": "Heeft deze zitbank een rugleuning?", + "es": "¿Este banco tiene un respaldo?", + "hu": "Van háttámlája ennek a padnak?", + "id": "Apakah bangku ini memiliki sandaran?", + "it": "Questa panchina ha lo schienale?", + "ru": "Есть ли у этой скамейки спинка?", + "zh_Hans": "这个长椅有靠背吗?", + "zh_Hant": "這個長椅是否有靠背?", + "nb_NO": "Har denne beken et rygglene?", + "pl": "Czy ta ławka ma oparcie?", + "pt_BR": "Este assento tem um escosto?" + }, + "id": "bench-backrest" + }, + { + "render": { + "en": "{seats} seats", + "de": "{seats} Sitzplätze", + "fr": "{seats} places", + "nl": "{seats} zitplaatsen", + "es": "{seats} asientos", + "hu": "{seats} ülőhely", + "id": "{seats} kursi", + "it": "{seats} posti", + "ru": "{seats} мест", + "zh_Hant": "{seats} 座位數", + "nb_NO": "{seats} seter", + "pl": "{seats} siedzeń", + "pt_BR": "{seats} assentos" + }, + "freeform": { + "key": "seats", + "type": "nat" + }, + "question": { + "en": "How many seats does this bench have?", + "de": "Wie viele Sitzplätze hat diese Bank?", + "fr": "De combien de places dispose ce banc ?", + "nl": "Hoeveel zitplaatsen heeft deze bank?", + "es": "¿Cuántos asientos tiene este banco?", + "hu": "Hány ülőhely van ezen a padon?", + "it": "Quanti posti ha questa panchina?", + "ru": "Сколько мест на этой скамейке?", + "zh_Hans": "这个长椅有几个座位?", + "zh_Hant": "這個長椅有幾個位子?", + "nb_NO": "Hvor mange sitteplasser har denne benken?", + "pl": "Ile siedzeń ma ta ławka?", + "pt_BR": "Quantos assentos este banco tem?" + }, + "id": "bench-seats" + }, + { + "render": { + "en": "Material: {material}", + "de": "Material: {material}", + "fr": "Matériau : {material}", + "nl": "Gemaakt van {material}", + "es": "Material: {material}", + "hu": "Anyag: {material}", + "it": "Materiale: {material}", + "ru": "Материал: {material}", + "zh_Hanå¨s": "材质: {material}", + "zh_Hant": "材質:{material}", + "nb_NO": "Materiale: {material}", + "fi": "Materiaali: {material}", + "zh_Hans": "材质: {material}", + "pl": "Materiał: {material}", + "pt_BR": "Material: {material}" + }, + "freeform": { + "key": "material", + "addExtraTags": [] + }, + "mappings": [ + { + "if": "material=wood", + "then": { + "en": "Material: wood", + "de": "Material: Holz", + "fr": "Matériau : bois", + "nl": "Gemaakt uit hout", + "es": "Material: madera", + "hu": "Anyag: fa", + "it": "Materiale: legno", + "ru": "Материал: дерево", + "zh_Hans": "材质:木", + "nb_NO": "Materiale: tre", + "zh_Hant": "材質:木頭", + "pt_BR": "Material: madeira", + "fi": "Materiaali: puu", + "pl": "Materiał: drewno" + } + }, + { + "if": "material=metal", + "then": { + "en": "Material: metal", + "de": "Material: Metall", + "fr": "Matériau : métal", + "nl": "Gemaakt uit metaal", + "es": "Material: metal", + "hu": "Anyag: fém", + "it": "Materiale: metallo", + "ru": "Материал: металл", + "zh_Hans": "材质:金属", + "nb_NO": "Materiale: metall", + "zh_Hant": "材質:金屬", + "pl": "Materiał: metal", + "pt_BR": "Material: metal" + } + }, + { + "if": "material=stone", + "then": { + "en": "Material: stone", + "de": "Material: Stein", + "fr": "Matériau : pierre", + "nl": "Gemaakt uit steen", + "es": "Material: piedra", + "hu": "Anyag: kő", + "it": "Materiale: pietra", + "ru": "Материал: камень", + "zh_Hans": "材质:石头", + "nb_NO": "Materiale: stein", + "zh_Hant": "材質:石頭", + "pt_BR": "Material: pedra", + "fi": "Materiaali: kivi", + "pl": "Materiał: kamień" + } + }, + { + "if": "material=concrete", + "then": { + "en": "Material: concrete", + "de": "Material: Beton", + "fr": "Matériau : béton", + "nl": "Gemaakt uit beton", + "es": "Material: concreto", + "hu": "Anyag: beton", + "it": "Materiale: cemento", + "ru": "Материал: бетон", + "zh_Hans": "材质:混凝土", + "nb_NO": "Materiale: betong", + "zh_Hant": "材質:水泥", + "pt_BR": "Material: concreto", + "fi": "Materiaali: betoni", + "pl": "Materiał: beton" + } + }, + { + "if": "material=plastic", + "then": { + "en": "Material: plastic", + "de": "Material: Kunststoff", + "fr": "Matériau : plastique", + "nl": "Gemaakt uit plastiek", + "es": "Material: plastico", + "hu": "Anyag: műanyag", + "it": "Materiale: plastica", + "ru": "Материал: пластик", + "zh_Hans": "材质:塑料", + "nb_NO": "Materiale: plastikk", + "zh_Hant": "材質:塑膠", + "pt_BR": "Material: plástico", + "fi": "Materiaali: muovi", + "pl": "Materiał: plastik" + } + }, + { + "if": "material=steel", + "then": { + "en": "Material: steel", + "de": "Material: Stahl", + "fr": "Matériau : acier", + "nl": "Gemaakt uit staal", + "es": "Material: acero", + "hu": "Anyag: acél", + "it": "Materiale: acciaio", + "ru": "Материал: сталь", + "zh_Hans": "材质:不锈钢", + "nb_NO": "Materiale: stål", + "zh_Hant": "材質:鋼鐵", + "pt_BR": "Material: aço", + "fi": "Materiaali: teräs", + "pl": "Materiał: stal" + } + } + ], + "question": { + "en": "What is the bench (seating) made from?", + "de": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", + "fr": "De quel matériau ce banc est-il fait ?", + "nl": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", + "hu": "Miből van a pad (ülő része)?", + "it": "Di che materiale è fatta questa panchina?", + "zh_Hans": "这个长椅(或座椅)是用什么材料做的?", + "ru": "Из какого материала сделана скамейка?", + "zh_Hant": "這個長椅 (座位) 是什麼做的?", + "pt_BR": "De que é feito o banco (assento)?", + "pl": "Z czego wykonana jest ławka (siedzisko)?" + }, + "id": "bench-material" + }, + { + "question": { + "en": "In which direction are you looking when sitting on the bench?", + "de": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", + "nl": "In welke richting kijk je wanneer je op deze zitbank zit?", + "fr": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", + "hu": "Milyen irányba néz a pad?", + "it": "In che direzione si guarda quando si è seduti su questa panchina?", + "ru": "В каком направлении вы смотрите, когда сидите на скамейке?", + "zh_Hans": "坐在长椅上的时候你目视的方向是哪边?", + "zh_Hant": "坐在長椅時是面對那個方向?", + "pt_BR": "Em que direção você olha quando está sentado no banco?", + "pl": "W jakim kierunku patrzysz siedząc na ławce?" + }, + "render": { + "en": "When sitting on the bench, one looks towards {direction}°.", + "de": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°.", + "nl": "Wanneer je op deze bank zit, dan kijk je in {direction}°.", + "fr": "Assis sur le banc, on regarde vers {direction}°.", + "hu": "A pad {direction}° felé néz.", + "it": "Quando si è seduti su questa panchina, si guarda verso {direction}°.", + "zh_Hans": "坐在长椅上的时候目视方向为 {direction}°方位。", + "ru": "Сидя на скамейке, вы смотрите в сторону {direction}°.", + "zh_Hant": "當坐在長椅時,那個人朝向 {direction}°。", + "pl": "Siedząc na ławce, patrzy się w kierunku {direction}°.", + "pt_BR": "Ao sentar-se no banco, olha-se para {direction} °." + }, + "freeform": { + "key": "direction", + "type": "direction" + }, + "id": "bench-direction" + }, + { + "render": { + "en": "Colour: {colour}", + "de": "Farbe: {colour}", + "fr": "Couleur : {colour}", + "nl": "Kleur: {colour}", + "hu": "Szín: {colour}", + "it": "Colore: {colour}", + "ru": "Цвет: {colour}", + "id": "Warna: {colour}", + "zh_Hans": "颜色: {colour}", + "zh_Hant": "顏色:{colour}", + "nb_NO": "Farge: {colour}", + "pt_BR": "Cor: {colour}", + "fi": "Väri: {colour}", + "pl": "Kolor: {colour}" + }, + "question": { + "en": "Which colour does this bench have?", + "de": "Welche Farbe hat diese Sitzbank?", + "fr": "Quelle est la couleur de ce banc ?", + "nl": "Welke kleur heeft deze zitbank?", + "hu": "Milyen színű a pad?", + "it": "Di che colore è questa panchina?", + "ru": "Какого цвета скамейка?", + "zh_Hans": "这个长椅是什么颜色的?", + "zh_Hant": "這個長椅是什麼顏色的?", + "pt_BR": "Qual a cor dessa bancada?", + "pl": "Jaki kolor ma ta ławka?" + }, + "freeform": { + "key": "colour", + "type": "color" + }, + "mappings": [ + { + "if": "colour=brown", + "then": { + "en": "Colour: brown", + "de": "Farbe: braun", + "fr": "Couleur : marron", + "nl": "De kleur is bruin", + "hu": "Szín: barna", + "it": "Colore: marrone", + "ru": "Цвет: коричневый", + "zh_Hans": "颜色:棕", + "zh_Hant": "顏色:棕色", + "nb_NO": "Farge: brun", + "pt_BR": "Cor: marrom", + "fi": "Väri: ruskea", + "pl": "Kolor: brązowy" + } + }, + { + "if": "colour=green", + "then": { + "en": "Colour: green", + "de": "Farbe: grün", + "fr": "Couleur : verte", + "nl": "De kleur is groen", + "hu": "Szín: zöld", + "it": "Colore: verde", + "ru": "Цвет: зеленый", + "zh_Hans": "颜色:绿", + "zh_Hant": "顏色:綠色", + "nb_NO": "Farge: grønn", + "pt_BR": "Cor: verde", + "fi": "Väri: vihreä", + "pl": "Kolor: zielony" + } + }, + { + "if": "colour=gray", + "then": { + "en": "Colour: gray", + "de": "Farbe: grau", + "fr": "Couleur : gris", + "nl": "De kleur is grijs", + "hu": "Szín: szürke", + "it": "Colore: grigio", + "ru": "Цвет: серый", + "zh_Hans": "颜色:灰", + "zh_Hant": "顏色:灰色", + "nb_NO": "Farge: grå", + "pt_BR": "Cor: cinza", + "fi": "Väri: harmaa", + "pl": "Kolor: szary" + } + }, + { + "if": "colour=white", + "then": { + "en": "Colour: white", + "de": "Farbe: weiß", + "fr": "Couleur : blanc", + "nl": "De kleur is wit", + "hu": "Szín: fehér", + "it": "Colore: bianco", + "ru": "Цвет: белый", + "zh_Hans": "颜色:白", + "zh_Hant": "顏色:白色", + "nb_NO": "Farge: hvit", + "pt_BR": "Cor: branco", + "fi": "Väri: valkoinen", + "pl": "Kolor: biały" + } + }, + { + "if": "colour=red", + "then": { + "en": "Colour: red", + "de": "Farbe: rot", + "fr": "Couleur : rouge", + "nl": "De kleur is rood", + "hu": "Szín: piros", + "it": "Colore: rosso", + "ru": "Цвет: красный", + "zh_Hans": "颜色:红", + "zh_Hant": "顏色:紅色", + "nb_NO": "Farge: rød", + "pt_BR": "Cor: vermelho", + "fi": "Väri: punainen", + "pl": "Kolor: czerwony" + } + }, + { + "if": "colour=black", + "then": { + "en": "Colour: black", + "de": "Farbe: schwarz", + "fr": "Couleur : noire", + "nl": "De kleur is zwart", + "hu": "Szín: fekete", + "it": "Colore: nero", + "ru": "Цвет: чёрный", + "zh_Hans": "颜色:黑", + "zh_Hant": "顏色:黑色", + "nb_NO": "Farge: svart", + "pt_BR": "Cor: preto", + "fi": "Väri: musta", + "pl": "Kolor: czarny" + } + }, + { + "if": "colour=blue", + "then": { + "en": "Colour: blue", + "de": "Farbe: blau", + "fr": "Couleur : bleu", + "nl": "De kleur is blauw", + "hu": "Szín: kék", + "it": "Colore: blu", + "ru": "Цвет: синий", + "zh_Hans": "颜色:蓝", + "zh_Hant": "顏色:藍色", + "nb_NO": "Farge: blå", + "pt_BR": "Cor: azul", + "fi": "Väri: sininen", + "pl": "Kolor: niebieski" + } + }, + { + "if": "colour=yellow", + "then": { + "en": "Colour: yellow", + "de": "Farbe: gelb", + "fr": "Couleur : jaune", + "nl": "De kleur is geel", + "hu": "Szín: sárga", + "it": "Colore: giallo", + "ru": "Цвет: желтый", + "zh_Hans": "颜色:黄", + "zh_Hant": "顏色:黃色", + "nb_NO": "Farge: gul", + "pt_BR": "Cor: amarelo", + "fi": "Väri: keltainen", + "pl": "Kolor: żółty" + } + } + ], + "id": "bench-colour" + }, + { + "question": { + "en": "When was this bench last surveyed?", + "nl": "Wanneer is deze laatste bank laatst gesurveyed?", + "fr": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", + "it": "Quando è stata verificata l’ultima volta questa panchina?", + "zh_Hans": "上次对这个长椅实地调查是什么时候?", + "de": "Wann wurde diese Bank zuletzt überprüft?", + "ru": "Когда последний раз обследовали эту скамейку?", + "zh_Hant": "上一次探察長椅是什麼時候?", + "pt_BR": "Quando esta bancada foi pesquisada pela última vez?", + "pl": "Kiedy ostatnio badano tę ławkę?" + }, + "render": { + "en": "This bench was last surveyed on {survey:date}", + "nl": "Deze bank is laatst gesurveyd op {survey:date}", + "fr": "Ce banc a été contrôlé pour la dernière fois le {survey:date}", + "it": "Questa panchina è stata controllata l’ultima volta in data {survey:date}", + "zh_Hans": "这个长椅于 {survey:date}最后一次实地调查", + "de": "Diese Bank wurde zuletzt überprüft am {survey:date}", + "ru": "Последний раз обследование этой скамейки проводилось {survey:date}", + "zh_Hant": "這個長椅最後是在 {survey:date} 探查的", + "pt_BR": "Esta bancada foi pesquisada pela última vez em {survey:date}", + "pl": "Ławka ta była ostatnio badana w dniu {survey:date}" + }, + "freeform": { + "key": "survey:date", + "type": "date" + }, + "mappings": [ + { + "if": "survey:date:={_now:date}", + "then": "Surveyed today!" + } + ], + "id": "bench-survey:date" + } + ], + "icon": { + "render": "circle:#FE6F32;./assets/layers/bench/bench.svg" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=bench" + ], + "title": { + "en": "bench", + "de": "sitzbank", + "fr": "banc", + "nl": "zitbank", + "es": "banco", + "it": "panchina", + "ru": "Скамейка", + "id": "bangku", + "zh_Hans": "长椅", + "nb_NO": "benk", + "zh_Hant": "長椅", + "pt_BR": "banco", + "fi": "penkki", + "pl": "Ławka" + }, + "presiceInput": { + "preferredBackground": "photo" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/bench_at_pt/bench_at_pt.json b/assets/layers/bench_at_pt/bench_at_pt.json index ff184b187..f619ededa 100644 --- a/assets/layers/bench_at_pt/bench_at_pt.json +++ b/assets/layers/bench_at_pt/bench_at_pt.json @@ -1,145 +1,147 @@ { - "id": "bench_at_pt", - "name": { - "en": "Benches at public transport stops", - "de": "Sitzbänke bei Haltestellen", - "fr": "Bancs des arrêts de transport en commun", - "nl": "Zitbanken aan bushaltes", - "es": "Bancos en una parada de transporte público", - "hu": "Padok megállókban", - "it": "Panchine alle fermate del trasporto pubblico", - "ru": "Скамейки на остановках общественного транспорта", - "zh_Hans": "在公交站点的长椅", - "nb_NO": "Benker", - "zh_Hant": "大眾運輸站點的長椅", - "pt_BR": "Bancos em pontos de transporte público", - "pl": "Ławki na przystankach komunikacji miejskiej" - }, - "minzoom": 14, - "source": { - "osmTags": { - "or": [ - "bench=yes", - "bench=stand_up_bench" - ] - } - }, - "title": { - "render": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "hu": "Pad", - "it": "Panchina", - "ru": "Скамейка", - "id": "Bangku", - "zh_Hans": "长椅", - "nb_NO": "Benk", - "zh_Hant": "長椅", - "pt_BR": "Banco", - "fi": "Penkki", - "pl": "Ławka" + "id": "bench_at_pt", + "name": { + "en": "Benches at public transport stops", + "de": "Sitzbänke bei Haltestellen", + "fr": "Bancs des arrêts de transport en commun", + "nl": "Zitbanken aan bushaltes", + "es": "Bancos en una parada de transporte público", + "hu": "Padok megállókban", + "it": "Panchine alle fermate del trasporto pubblico", + "ru": "Скамейки на остановках общественного транспорта", + "zh_Hans": "在公交站点的长椅", + "nb_NO": "Benker", + "zh_Hant": "大眾運輸站點的長椅", + "pt_BR": "Bancos em pontos de transporte público", + "pl": "Ławki na przystankach komunikacji miejskiej" }, - "mappings": [ - { - "if": { - "or": [ - "public_transport=platform", - "railway=platform", - "highway=bus_stop" - ] - }, - "then": { - "en": "Bench at public transport stop", - "de": "Sitzbank bei Haltestelle", - "fr": "Banc d'un arrêt de transport en commun", - "nl": "Zitbank aan een bushalte", - "hu": "Pad megállóban", - "it": "Panchina alla fermata del trasporto pubblico", - "ru": "Скамейка на остановке общественного транспорта", - "zh_Hans": "在公交站点的长椅", - "zh_Hant": "大眾運輸站點的長椅", - "pt_BR": "Banco em ponto de transporte público", - "pl": "Ławka na przystanku komunikacji miejskiej" + "minzoom": 14, + "source": { + "osmTags": { + "or": [ + "bench=yes", + "bench=stand_up_bench" + ] } - }, - { - "if": { - "and": [ - "amenity=shelter" - ] - }, - "then": { - "en": "Bench in shelter", - "de": "Sitzbank in Unterstand", - "fr": "Banc dans un abri", - "nl": "Zitbank in een schuilhokje", - "hu": "Pad fedett helyen", - "it": "Panchina in un riparo", - "zh_Hans": "在庇护所的长椅", - "ru": "Скамейка в укрытии", - "zh_Hant": "涼亭內的長椅", - "pt_BR": "Banco em abrigo" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "{name}", - "de": "{name}", - "fr": "{name}", - "nl": "{name}", - "hu": "{name}", - "it": "{name}", - "ru": "{name}", - "id": "{name}", - "zh_Hans": "{name}", - "zh_Hant": "{name}", - "pt_BR": "{name}", - "fi": "{name}", - "pl": "{name}" - }, - "freeform": { - "key": "name" - } }, - { - "render": { - "en": "Stand up bench", - "de": "Stehbank", - "fr": "Banc assis debout", - "nl": "Leunbank", - "it": "Panca in piedi", - "zh_Hans": "站立长凳", - "ru": "Встаньте на скамейке", - "zh_Hant": "站立長椅" - }, - "freeform": { - "key": "bench", - "addExtraTags": [] - }, - "condition": { - "and": [ - "bench=stand_up_bench" + "title": { + "render": { + "en": "Bench", + "de": "Sitzbank", + "fr": "Banc", + "nl": "Zitbank", + "es": "Banco", + "hu": "Pad", + "it": "Panchina", + "ru": "Скамейка", + "id": "Bangku", + "zh_Hans": "长椅", + "nb_NO": "Benk", + "zh_Hant": "長椅", + "pt_BR": "Banco", + "fi": "Penkki", + "pl": "Ławka" + }, + "mappings": [ + { + "if": { + "or": [ + "public_transport=platform", + "railway=platform", + "highway=bus_stop" + ] + }, + "then": { + "en": "Bench at public transport stop", + "de": "Sitzbank bei Haltestelle", + "fr": "Banc d'un arrêt de transport en commun", + "nl": "Zitbank aan een bushalte", + "hu": "Pad megállóban", + "it": "Panchina alla fermata del trasporto pubblico", + "ru": "Скамейка на остановке общественного транспорта", + "zh_Hans": "在公交站点的长椅", + "zh_Hant": "大眾運輸站點的長椅", + "pt_BR": "Banco em ponto de transporte público", + "pl": "Ławka na przystanku komunikacji miejskiej" + } + }, + { + "if": { + "and": [ + "amenity=shelter" + ] + }, + "then": { + "en": "Bench in shelter", + "de": "Sitzbank in Unterstand", + "fr": "Banc dans un abri", + "nl": "Zitbank in een schuilhokje", + "hu": "Pad fedett helyen", + "it": "Panchina in un riparo", + "zh_Hans": "在庇护所的长椅", + "ru": "Скамейка в укрытии", + "zh_Hant": "涼亭內的長椅", + "pt_BR": "Banco em abrigo" + } + } ] - } + }, + "tagRenderings": [ + "images", + { + "render": { + "en": "{name}", + "de": "{name}", + "fr": "{name}", + "nl": "{name}", + "hu": "{name}", + "it": "{name}", + "ru": "{name}", + "id": "{name}", + "zh_Hans": "{name}", + "zh_Hant": "{name}", + "pt_BR": "{name}", + "fi": "{name}", + "pl": "{name}" + }, + "freeform": { + "key": "name" + }, + "id": "bench_at_pt-name" + }, + { + "render": { + "en": "Stand up bench", + "de": "Stehbank", + "fr": "Banc assis debout", + "nl": "Leunbank", + "it": "Panca in piedi", + "zh_Hans": "站立长凳", + "ru": "Встаньте на скамейке", + "zh_Hant": "站立長椅" + }, + "freeform": { + "key": "bench", + "addExtraTags": [] + }, + "condition": { + "and": [ + "bench=stand_up_bench" + ] + }, + "id": "bench_at_pt-bench" + } + ], + "icon": { + "render": "./assets/themes/benches/bench_public_transport.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" } - ], - "icon": { - "render": "./assets/themes/benches/bench_public_transport.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - } } \ No newline at end of file diff --git a/assets/layers/bicycle_library/bicycle_library.json b/assets/layers/bicycle_library/bicycle_library.json index 589cf99ec..21e478e7b 100644 --- a/assets/layers/bicycle_library/bicycle_library.json +++ b/assets/layers/bicycle_library/bicycle_library.json @@ -1,268 +1,271 @@ { - "id": "bicycle_library", - "name": { - "en": "Bicycle library", - "nl": "Fietsbibliotheek", - "fr": "Vélothèque", - "it": "Bici in prestito", - "ru": "Велосипедная библиотека", - "zh_Hant": "單車圖書館", - "pt_BR": "Biblioteca de bicicleta" - }, - "minzoom": 8, - "source": { - "osmTags": "amenity=bicycle_library" - }, - "title": { - "render": { - "en": "Bicycle library", - "nl": "Fietsbibliotheek", - "fr": "Vélothèque", - "it": "Bici in prestito", - "ru": "Велосипедная библиотека", - "zh_Hant": "單車圖書館", - "pt_BR": "Biblioteca de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - } - ] - }, - "titleIcons": [ - { - "condition": { - "or": [ - "service:bicycle:pump=yes", - "service:bicycle:pump=separate" - ] - }, - "render": "" - }, - "defaults" - ], - "description": { - "en": "A facility where bicycles can be lent for longer period of times", - "nl": "Een plaats waar men voor langere tijd een fiets kan lenen", - "fr": "Un lieu où des vélos peuvent être empruntés pour un temps plus long", - "hu": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", - "it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi", - "de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", - "ru": "Учреждение, где велосипед может быть арендован на более длительный срок", - "zh_Hant": "能夠長期租用單車的設施", - "pt_BR": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos", - "pl": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "What is the name of this bicycle library?", - "nl": "Wat is de naam van deze fietsbieb?", - "fr": "Quel est le nom de cette vélothèque ?", - "it": "Qual è il nome di questo “bici in prestito”?", - "ru": "Как называется эта велосипедная библиотека?", - "nb_NO": "Hva heter dette sykkelbiblioteket?", - "zh_Hant": "這個單車圖書館的名稱是?", - "pt_BR": "Qual o nome desta biblioteca de bicicleta?" - }, - "render": { - "en": "This bicycle library is called {name}", - "nl": "Deze fietsbieb heet {name}", - "fr": "Cette vélothèque s'appelle {name}", - "it": "Il “bici in prestito” è chiamato {name}", - "ru": "Эта велосипедная библиотека называется {name}", - "nb_NO": "Dette sykkelbiblioteket heter {name}", - "zh_Hant": "這個單車圖書館叫做 {name}", - "pt_BR": "Esta biblioteca de bicicleta é chamada de {name}" - }, - "freeform": { - "key": "name" - } - }, - "website", - "phone", - "email", - "opening_hours", - { - "question": { - "en": "How much does lending a bicycle cost?", - "nl": "Hoeveel kost het huren van een fiets?", - "fr": "Combien coûte l'emprunt d'un vélo ?", - "hu": "Mennyibe kerül egy kerékpár kölcsönzése?", - "it": "Quanto costa il prestito di una bicicletta?", - "ru": "Сколько стоит прокат велосипеда?", - "de": "Wie viel kostet das Ausleihen eines Fahrrads?", - "nb_NO": "Hvor mye koster det å leie en sykkel?", - "zh_Hant": "租用單車的費用多少?", - "pt_BR": "Quanto custa um empréstimo de bicicleta?" - }, - "render": { - "en": "Lending a bicycle costs {charge}", - "nl": "Een fiets huren kost {charge}", - "fr": "Emprunter un vélo coûte {charge}", - "hu": "Egy kerékpár kölcsönzése {charge}", - "it": "Il prestito di una bicicletta costa {charge}", - "ru": "Стоимость аренды велосипеда {charge}", - "de": "Das Ausleihen eines Fahrrads kostet {charge}", - "nb_NO": "Sykkelleie koster {charge}", - "zh_Hant": "租借單車需要 {charge}", - "pt_BR": "Custos de empréstimo de bicicleta {charge}" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "en": "Lending a bicycle is free", - "nl": "Een fiets huren is gratis", - "fr": "L'emprunt de vélo est gratuit", - "hu": "A kerékpárkölcsönzés ingyenes", - "it": "Il prestito di una bicicletta è gratuito", - "de": "Das Ausleihen eines Fahrrads ist kostenlos", - "ru": "Прокат велосипедов бесплатен", - "nb_NO": "Det er gratis å leie en sykkel", - "zh_Hant": "租借單車免費", - "pt_BR": "Emprestar uma bicicleta é grátis" - } - }, - { - "if": { - "and": [ - "fee=yes", - "charge=€20warranty + €20/year" - ] - }, - "then": { - "en": "Lending a bicycle costs €20/year and €20 warranty", - "nl": "Een fiets huren kost €20/jaar en €20 waarborg", - "fr": "Emprunter un vélo coûte 20 €/an et 20 € de garantie", - "it": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia", - "de": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr", - "zh_Hant": "租借單車價錢 €20/year 與 €20 保證金", - "ru": "Прокат велосипеда стоит €20/год и €20 залог", - "pt_BR": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" - } - } - ] - }, - { - "question": { - "en": "Who can lend bicycles here?", - "nl": "Voor wie worden hier fietsen aangeboden?", - "fr": "Qui peut emprunter des vélos ici ?", - "hu": "Ki kölcsönözhet itt kerékpárt?", - "it": "Chi può prendere in prestito le biciclette qua?", - "zh_Hans": "谁可以从这里借自行车?", - "de": "Wer kann hier Fahrräder ausleihen?", - "ru": "Кто здесь может арендовать велосипед?", - "zh_Hant": "誰可以在這裡租單車?", - "pt_BR": "Quem pode emprestar bicicletas aqui?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "bicycle_library:for=child", - "then": { - "nl": "Aanbod voor kinderen", - "en": "Bikes for children available", - "fr": "Vélos pour enfants disponibles", - "hu": "", - "it": "Sono disponibili biciclette per bambini", - "de": "Fahrräder für Kinder verfügbar", - "ru": "Доступны детские велосипеды", - "zh_Hant": "提供兒童單車", - "pt_BR": "Bicicletas para crianças disponíveis" - } - }, - { - "if": "bicycle_library:for=adult", - "then": { - "nl": "Aanbod voor volwassenen", - "en": "Bikes for adult available", - "fr": "Vélos pour adultes disponibles", - "it": "Sono disponibili biciclette per adulti", - "de": "Fahrräder für Erwachsene verfügbar", - "ru": "Доступны велосипеды для взрослых", - "zh_Hant": "有提供成人單車", - "pt_BR": "Bicicletas para adulto disponíveis" - } - }, - { - "if": "bicycle_library:for=disabled", - "then": { - "nl": "Aanbod voor personen met een handicap", - "en": "Bikes for disabled persons available", - "fr": "Vélos pour personnes handicapées disponibles", - "it": "Sono disponibili biciclette per disabili", - "de": "Fahrräder für Behinderte verfügbar", - "ru": "Доступны велосипеды для людей с ограниченными возможностями", - "zh_Hant": "有提供行動不便人士的單車", - "pt_BR": "Bicicletas para deficientes físicos disponíveis" - } - } - ] - }, - "description" - ], - "presets": [ - { - "title": { - "en": "Fietsbibliotheek", - "nl": "Bicycle library", - "ru": "Велосипедная библиотека", - "zh_Hant": "自行車圖書館 ( Fietsbibliotheek)", - "it": "Bici in prestito", + "id": "bicycle_library", + "name": { + "en": "Bicycle library", + "nl": "Fietsbibliotheek", "fr": "Vélothèque", - "pt_BR": "Biblioteca de bicicletas" - }, - "tags": [ - "amenity=bicycle_library" - ], - "description": { - "nl": "Een fietsbieb heeft een collectie fietsen die leden mogen lenen", - "en": "A bicycle library has a collection of bikes which can be lent", - "fr": "Une vélothèque a une flotte de vélos qui peuvent être empruntés", - "it": "Una ciclo-teca o «bici in prestito» ha una collezione di bici che possno essere prestate", - "ru": "В велосипедной библиотеке есть велосипеды для аренды", - "zh_Hant": "單車圖書館有一大批單車供人租借" - } - } - ], - "icon": { - "render": "pin:#22ff55;./assets/layers/bicycle_library/bicycle_library.svg" - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "it": "Bici in prestito", + "ru": "Велосипедная библиотека", + "zh_Hant": "單車圖書館", + "pt_BR": "Biblioteca de bicicleta" }, - { - "if": "service:bicycle:pump=yes", - "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#c00" - }, - "wayHandling": 2 + "minzoom": 8, + "source": { + "osmTags": "amenity=bicycle_library" + }, + "title": { + "render": { + "en": "Bicycle library", + "nl": "Fietsbibliotheek", + "fr": "Vélothèque", + "it": "Bici in prestito", + "ru": "Велосипедная библиотека", + "zh_Hant": "單車圖書館", + "pt_BR": "Biblioteca de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": "{name}" + } + ] + }, + "titleIcons": [ + { + "condition": { + "or": [ + "service:bicycle:pump=yes", + "service:bicycle:pump=separate" + ] + }, + "render": "" + }, + "defaults" + ], + "description": { + "en": "A facility where bicycles can be lent for longer period of times", + "nl": "Een plaats waar men voor langere tijd een fiets kan lenen", + "fr": "Un lieu où des vélos peuvent être empruntés pour un temps plus long", + "hu": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", + "it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi", + "de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", + "ru": "Учреждение, где велосипед может быть арендован на более длительный срок", + "zh_Hant": "能夠長期租用單車的設施", + "pt_BR": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos", + "pl": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "What is the name of this bicycle library?", + "nl": "Wat is de naam van deze fietsbieb?", + "fr": "Quel est le nom de cette vélothèque ?", + "it": "Qual è il nome di questo “bici in prestito”?", + "ru": "Как называется эта велосипедная библиотека?", + "nb_NO": "Hva heter dette sykkelbiblioteket?", + "zh_Hant": "這個單車圖書館的名稱是?", + "pt_BR": "Qual o nome desta biblioteca de bicicleta?" + }, + "render": { + "en": "This bicycle library is called {name}", + "nl": "Deze fietsbieb heet {name}", + "fr": "Cette vélothèque s'appelle {name}", + "it": "Il “bici in prestito” è chiamato {name}", + "ru": "Эта велосипедная библиотека называется {name}", + "nb_NO": "Dette sykkelbiblioteket heter {name}", + "zh_Hant": "這個單車圖書館叫做 {name}", + "pt_BR": "Esta biblioteca de bicicleta é chamada de {name}" + }, + "freeform": { + "key": "name" + }, + "id": "bicycle_library-name" + }, + "website", + "phone", + "email", + "opening_hours", + { + "question": { + "en": "How much does lending a bicycle cost?", + "nl": "Hoeveel kost het huren van een fiets?", + "fr": "Combien coûte l'emprunt d'un vélo ?", + "hu": "Mennyibe kerül egy kerékpár kölcsönzése?", + "it": "Quanto costa il prestito di una bicicletta?", + "ru": "Сколько стоит прокат велосипеда?", + "de": "Wie viel kostet das Ausleihen eines Fahrrads?", + "nb_NO": "Hvor mye koster det å leie en sykkel?", + "zh_Hant": "租用單車的費用多少?", + "pt_BR": "Quanto custa um empréstimo de bicicleta?" + }, + "render": { + "en": "Lending a bicycle costs {charge}", + "nl": "Een fiets huren kost {charge}", + "fr": "Emprunter un vélo coûte {charge}", + "hu": "Egy kerékpár kölcsönzése {charge}", + "it": "Il prestito di una bicicletta costa {charge}", + "ru": "Стоимость аренды велосипеда {charge}", + "de": "Das Ausleihen eines Fahrrads kostet {charge}", + "nb_NO": "Sykkelleie koster {charge}", + "zh_Hant": "租借單車需要 {charge}", + "pt_BR": "Custos de empréstimo de bicicleta {charge}" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Lending a bicycle is free", + "nl": "Een fiets huren is gratis", + "fr": "L'emprunt de vélo est gratuit", + "hu": "A kerékpárkölcsönzés ingyenes", + "it": "Il prestito di una bicicletta è gratuito", + "de": "Das Ausleihen eines Fahrrads ist kostenlos", + "ru": "Прокат велосипедов бесплатен", + "nb_NO": "Det er gratis å leie en sykkel", + "zh_Hant": "租借單車免費", + "pt_BR": "Emprestar uma bicicleta é grátis" + } + }, + { + "if": { + "and": [ + "fee=yes", + "charge=€20warranty + €20/year" + ] + }, + "then": { + "en": "Lending a bicycle costs €20/year and €20 warranty", + "nl": "Een fiets huren kost €20/jaar en €20 waarborg", + "fr": "Emprunter un vélo coûte 20 €/an et 20 € de garantie", + "it": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia", + "de": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr", + "zh_Hant": "租借單車價錢 €20/year 與 €20 保證金", + "ru": "Прокат велосипеда стоит €20/год и €20 залог", + "pt_BR": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" + } + } + ], + "id": "bicycle_library-charge" + }, + { + "id": "bicycle-library-target-group", + "question": { + "en": "Who can lend bicycles here?", + "nl": "Voor wie worden hier fietsen aangeboden?", + "fr": "Qui peut emprunter des vélos ici ?", + "hu": "Ki kölcsönözhet itt kerékpárt?", + "it": "Chi può prendere in prestito le biciclette qua?", + "zh_Hans": "谁可以从这里借自行车?", + "de": "Wer kann hier Fahrräder ausleihen?", + "ru": "Кто здесь может арендовать велосипед?", + "zh_Hant": "誰可以在這裡租單車?", + "pt_BR": "Quem pode emprestar bicicletas aqui?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "bicycle_library:for=child", + "then": { + "nl": "Aanbod voor kinderen", + "en": "Bikes for children available", + "fr": "Vélos pour enfants disponibles", + "hu": "", + "it": "Sono disponibili biciclette per bambini", + "de": "Fahrräder für Kinder verfügbar", + "ru": "Доступны детские велосипеды", + "zh_Hant": "提供兒童單車", + "pt_BR": "Bicicletas para crianças disponíveis" + } + }, + { + "if": "bicycle_library:for=adult", + "then": { + "nl": "Aanbod voor volwassenen", + "en": "Bikes for adult available", + "fr": "Vélos pour adultes disponibles", + "it": "Sono disponibili biciclette per adulti", + "de": "Fahrräder für Erwachsene verfügbar", + "ru": "Доступны велосипеды для взрослых", + "zh_Hant": "有提供成人單車", + "pt_BR": "Bicicletas para adulto disponíveis" + } + }, + { + "if": "bicycle_library:for=disabled", + "then": { + "nl": "Aanbod voor personen met een handicap", + "en": "Bikes for disabled persons available", + "fr": "Vélos pour personnes handicapées disponibles", + "it": "Sono disponibili biciclette per disabili", + "de": "Fahrräder für Behinderte verfügbar", + "ru": "Доступны велосипеды для людей с ограниченными возможностями", + "zh_Hant": "有提供行動不便人士的單車", + "pt_BR": "Bicicletas para deficientes físicos disponíveis" + } + } + ] + }, + "description" + ], + "presets": [ + { + "title": { + "en": "Fietsbibliotheek", + "nl": "Bicycle library", + "ru": "Велосипедная библиотека", + "zh_Hant": "自行車圖書館 ( Fietsbibliotheek)", + "it": "Bici in prestito", + "fr": "Vélothèque", + "pt_BR": "Biblioteca de bicicletas" + }, + "tags": [ + "amenity=bicycle_library" + ], + "description": { + "nl": "Een fietsbieb heeft een collectie fietsen die leden mogen lenen", + "en": "A bicycle library has a collection of bikes which can be lent", + "fr": "Une vélothèque a une flotte de vélos qui peuvent être empruntés", + "it": "Una ciclo-teca o «bici in prestito» ha una collezione di bici che possno essere prestate", + "ru": "В велосипедной библиотеке есть велосипеды для аренды", + "zh_Hant": "單車圖書館有一大批單車供人租借" + } + } + ], + "icon": { + "render": "pin:#22ff55;./assets/layers/bicycle_library/bicycle_library.svg" + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + }, + { + "if": "service:bicycle:pump=yes", + "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#c00" + }, + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index d7aede718..665a75942 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -1,69 +1,6 @@ { - "id": "bicycle_tube_vending_machine", - "name": { - "en": "Bicycle tube vending machine", - "nl": "Fietsbanden-verkoopsautomaat", - "fr": "Distributeur automatique de chambre à air de vélo", - "it": "Distributore automatico di camere d’aria per bici", - "de": "Fahrradschlauch-Automat", - "ru": "Торговый автомат для велосипедистов", - "zh_Hant": "自行車內胎自動售貨機", - "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "title": { - "render": { - "en": "Bicycle tube vending machine", - "nl": "Fietsbanden-verkoopsautomaat", - "fr": "Distributeur automatique de chambre à air de vélo", - "it": "Distributore automatico di camere d’aria per bici", - "de": "Fahrradschlauch-Automat", - "ru": "Торговый автомат для велосипедистов", - "zh_Hant": "自行車內胎自動售貨機", - "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": "Bicycle tube vending machine {name}" - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent" - }, - "defaults" - ], - "icon": { - "render": "pin:#ffffff;./assets/layers/bicycle_tube_vending_machine/pinIcon.svg" - }, - "iconOverlays": [ - { - "if": { - "or": [ - "operational_status=broken", - "operational_status=closed" - ] - }, - "then": "close:#c33", - "badge": true - } - ], - "iconSize": "50,50,bottom", - "source": { - "osmTags": { - "and": [ - "amenity=vending_machine", - "vending~.*bicycle_tube.*" - ] - } - }, - "minzoom": 13, - "wayHandling": 2, - "presets": [ - { - "title": { + "id": "bicycle_tube_vending_machine", + "name": { "en": "Bicycle tube vending machine", "nl": "Fietsbanden-verkoopsautomaat", "fr": "Distributeur automatique de chambre à air de vélo", @@ -72,183 +9,251 @@ "ru": "Торговый автомат для велосипедистов", "zh_Hant": "自行車內胎自動售貨機", "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "tags": [ - "amenity=vending_machine", - "vending=bicycle_tube", - "vending:bicycle_tube=yes" - ] - } - ], - "color": "#6bc4f7", - "tagRenderings": [ - "images", - { - "#": "Still in use?", - "question": { - "en": "Is this vending machine still operational?", - "nl": "Is deze verkoopsautomaat nog steeds werkende?", - "fr": "Cette machine est-elle encore opérationelle ?", - "it": "Questo distributore automatico funziona ancora?", - "ru": "Этот торговый автомат все еще работает?", - "de": "Ist dieser Automat noch in Betrieb?", - "zh_Hant": "這個自動販賣機仍有運作嗎?", - "pt_BR": "Esta máquina de venda automática ainda está operacional?" - }, - "render": { - "en": "The operational status is {operational_status", - "nl": "Deze verkoopsautomaat is {operational_status}", - "fr": "L'état opérationnel est {operational_status}", - "it": "Lo stato operativo è {operational_status}", - "de": "Der Betriebszustand ist {operational_status", - "ru": "Рабочий статус: {operational_status", - "zh_Hant": "運作狀態是 {operational_status", - "pt_BR": "O estado operacional é: {operational_status" - }, - "freeform": { - "key": "operational_status" - }, - "mappings": [ - { - "if": "operational_status=", - "then": { - "en": "This vending machine works", - "nl": "Deze verkoopsautomaat werkt", - "fr": "Le distributeur automatique fonctionne", - "hu": "Az automata működik", - "it": "Il distributore automatico funziona", - "ru": "Этот торговый автомат работает", - "zh_Hans": "这个借还机正常工作", - "de": "Dieser Automat funktioniert", - "zh_Hant": "這個自動販賣機仍運作", - "pt_BR": "Esta máquina de venda automática funciona" - } - }, - { - "if": "operational_status=broken", - "then": { - "en": "This vending machine is broken", - "nl": "Deze verkoopsautomaat is kapot", - "fr": "Le distributeur automatique est en panne", - "hu": "Az automata elromlott", - "it": "Il distributore automatico è guasto", - "ru": "Этот торговый автомат сломан", - "zh_Hans": "这个借还机已经损坏", - "de": "Dieser Automat ist kaputt", - "zh_Hant": "這個自動販賣機沒有運作了", - "pt_BR": "Esta máquina de venda automática está quebrada" - } - }, - { - "if": "operational_status=closed", - "then": { - "en": "This vending machine is closed", - "nl": "Deze verkoopsautomaat is uitgeschakeld", - "fr": "Le distributeur automatique est fermé", - "hu": "Az automata zárva van", - "it": "Il distributore automatico è spento", - "ru": "Этот торговый автомат закрыт", - "zh_Hans": "这个借还机被关闭了", - "de": "Dieser Automat ist geschlossen", - "zh_Hant": "這個自動販賣機已經關閉了", - "pt_BR": "Esta máquina de venda automática está fechada" - } - } - ] }, - { - "question": "How much does a bicycle tube cost?", - "render": "A bicycle tube costs {charge}", - "freeform": { - "key": "charge" - } + "title": { + "render": { + "en": "Bicycle tube vending machine", + "nl": "Fietsbanden-verkoopsautomaat", + "fr": "Distributeur automatique de chambre à air de vélo", + "it": "Distributore automatico di camere d’aria per bici", + "de": "Fahrradschlauch-Automat", + "ru": "Торговый автомат для велосипедистов", + "zh_Hant": "自行車內胎自動售貨機", + "pt_BR": "Máquina de venda automática de tubos de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": "Bicycle tube vending machine {name}" + } + ] }, - { - "question": "How can one pay at this tube vending machine?", - "mappings": [ + "titleIcons": [ { - "if": "payment:coins=yes", - "ifnot": "payment:coins=no", - "then": "Payment with coins is possible" + "render": "", + "condition": "operator=De Fietsambassade Gent" }, - { - "if": "payment:notes=yes", - "ifnot": "payment:notes=no", - "then": "Payment with notes is possible" - }, - { - "if": "payment:cards=yes", - "ifnot": "payment:cards=no", - "then": "Payment with cards is possible" - } - ], - "multiAnswer": true + "defaults" + ], + "icon": { + "render": "pin:#ffffff;./assets/layers/bicycle_tube_vending_machine/pinIcon.svg" }, - { - "question": "Which brand of tubes are sold here?", - "freeform": { - "key": "brand" - }, - "render": "{brand} tubes are sold here", - "mappings": [ + "iconOverlays": [ { - "if": "brand=Continental", - "then": "Continental tubes are sold here" - }, - { - "if": "brand=Schwalbe", - "then": "Schwalbe tubes are sold here" + "if": { + "or": [ + "operational_status=broken", + "operational_status=closed" + ] + }, + "then": "close:#c33", + "badge": true + } + ], + "iconSize": "50,50,bottom", + "source": { + "osmTags": { + "and": [ + "amenity=vending_machine", + "vending~.*bicycle_tube.*" + ] } - ], - "multiAnswer": true }, - { - "question": "Who maintains this vending machine?", - "render": "This vending machine is maintained by {operator}", - "mappings": [ + "minzoom": 13, + "wayHandling": 2, + "presets": [ { - "if": "operator=Schwalbe", - "then": "Maintained by Schwalbe" - }, - { - "if": "operator=Continental", - "then": "Maintained by Continental" + "title": { + "en": "Bicycle tube vending machine", + "nl": "Fietsbanden-verkoopsautomaat", + "fr": "Distributeur automatique de chambre à air de vélo", + "it": "Distributore automatico di camere d’aria per bici", + "de": "Fahrradschlauch-Automat", + "ru": "Торговый автомат для велосипедистов", + "zh_Hant": "自行車內胎自動售貨機", + "pt_BR": "Máquina de venda automática de tubos de bicicleta" + }, + "tags": [ + "amenity=vending_machine", + "vending=bicycle_tube", + "vending:bicycle_tube=yes" + ] } - ], - "freeform": { - "key": "operator" - } - }, - { - "question": "Are other bicycle bicycle accessories sold here?", - "mappings": [ + ], + "color": "#6bc4f7", + "tagRenderings": [ + "images", { - "if": "vending:bicycle_light=yes", - "ifnot": "vending:bicycle_light=no", - "then": "Bicycle lights are sold here" + "question": { + "en": "Is this vending machine still operational?", + "nl": "Is deze verkoopsautomaat nog steeds werkende?", + "fr": "Cette machine est-elle encore opérationelle ?", + "it": "Questo distributore automatico funziona ancora?", + "ru": "Этот торговый автомат все еще работает?", + "de": "Ist dieser Automat noch in Betrieb?", + "zh_Hant": "這個自動販賣機仍有運作嗎?", + "pt_BR": "Esta máquina de venda automática ainda está operacional?" + }, + "render": { + "en": "The operational status is {operational_status", + "nl": "Deze verkoopsautomaat is {operational_status}", + "fr": "L'état opérationnel est {operational_status}", + "it": "Lo stato operativo è {operational_status}", + "de": "Der Betriebszustand ist {operational_status", + "ru": "Рабочий статус: {operational_status", + "zh_Hant": "運作狀態是 {operational_status", + "pt_BR": "O estado operacional é: {operational_status" + }, + "freeform": { + "key": "operational_status" + }, + "mappings": [ + { + "if": "operational_status=", + "then": { + "en": "This vending machine works", + "nl": "Deze verkoopsautomaat werkt", + "fr": "Le distributeur automatique fonctionne", + "hu": "Az automata működik", + "it": "Il distributore automatico funziona", + "ru": "Этот торговый автомат работает", + "zh_Hans": "这个借还机正常工作", + "de": "Dieser Automat funktioniert", + "zh_Hant": "這個自動販賣機仍運作", + "pt_BR": "Esta máquina de venda automática funciona" + } + }, + { + "if": "operational_status=broken", + "then": { + "en": "This vending machine is broken", + "nl": "Deze verkoopsautomaat is kapot", + "fr": "Le distributeur automatique est en panne", + "hu": "Az automata elromlott", + "it": "Il distributore automatico è guasto", + "ru": "Этот торговый автомат сломан", + "zh_Hans": "这个借还机已经损坏", + "de": "Dieser Automat ist kaputt", + "zh_Hant": "這個自動販賣機沒有運作了", + "pt_BR": "Esta máquina de venda automática está quebrada" + } + }, + { + "if": "operational_status=closed", + "then": { + "en": "This vending machine is closed", + "nl": "Deze verkoopsautomaat is uitgeschakeld", + "fr": "Le distributeur automatique est fermé", + "hu": "Az automata zárva van", + "it": "Il distributore automatico è spento", + "ru": "Этот торговый автомат закрыт", + "zh_Hans": "这个借还机被关闭了", + "de": "Dieser Automat ist geschlossen", + "zh_Hant": "這個自動販賣機已經關閉了", + "pt_BR": "Esta máquina de venda automática está fechada" + } + } + ], + "id": "Still in use?" }, { - "if": "vending:gloves=yes", - "ifnot": "vending:gloves=no", - "then": "Gloves are sold here" + "question": "How much does a bicycle tube cost?", + "render": "A bicycle tube costs {charge}", + "freeform": { + "key": "charge" + }, + "id": "bicycle_tube_vending_machine-charge" }, { - "if": "vending:bicycle_repair_kit=yes", - "ifnot": "vending:bicycle_repair_kit=no", - "then": "Bicycle repair kits are sold here" + "id": "vending-machine-payment-methods", + "question": "How can one pay at this tube vending machine?", + "mappings": [ + { + "if": "payment:coins=yes", + "ifnot": "payment:coins=no", + "then": "Payment with coins is possible" + }, + { + "if": "payment:notes=yes", + "ifnot": "payment:notes=no", + "then": "Payment with notes is possible" + }, + { + "if": "payment:cards=yes", + "ifnot": "payment:cards=no", + "then": "Payment with cards is possible" + } + ], + "multiAnswer": true }, { - "if": "vending:bicycle_pump=yes", - "ifnot": "vending:bicycle_pump=no", - "then": "Bicycle pumps are sold here" + "question": "Which brand of tubes are sold here?", + "freeform": { + "key": "brand" + }, + "render": "{brand} tubes are sold here", + "mappings": [ + { + "if": "brand=Continental", + "then": "Continental tubes are sold here" + }, + { + "if": "brand=Schwalbe", + "then": "Schwalbe tubes are sold here" + } + ], + "multiAnswer": true, + "id": "bicycle_tube_vending_machine-brand" }, { - "if": "vending:bicycle_lock=yes", - "ifnot": "vending:bicycle_lock=no", - "then": "Bicycle locks are sold here" + "question": "Who maintains this vending machine?", + "render": "This vending machine is maintained by {operator}", + "mappings": [ + { + "if": "operator=Schwalbe", + "then": "Maintained by Schwalbe" + }, + { + "if": "operator=Continental", + "then": "Maintained by Continental" + } + ], + "freeform": { + "key": "operator" + }, + "id": "bicycle_tube_vending_machine-operator" + }, + { + "id": "bicycle_tube_vending_maching-other-items", + "question": "Are other bicycle bicycle accessories sold here?", + "mappings": [ + { + "if": "vending:bicycle_light=yes", + "ifnot": "vending:bicycle_light=no", + "then": "Bicycle lights are sold here" + }, + { + "if": "vending:gloves=yes", + "ifnot": "vending:gloves=no", + "then": "Gloves are sold here" + }, + { + "if": "vending:bicycle_repair_kit=yes", + "ifnot": "vending:bicycle_repair_kit=no", + "then": "Bicycle repair kits are sold here" + }, + { + "if": "vending:bicycle_pump=yes", + "ifnot": "vending:bicycle_pump=no", + "then": "Bicycle pumps are sold here" + }, + { + "if": "vending:bicycle_lock=yes", + "ifnot": "vending:bicycle_lock=no", + "then": "Bicycle locks are sold here" + } + ], + "multiAnswer": true } - ], - "multiAnswer": true - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/bike_cafe/bike_cafe.json b/assets/layers/bike_cafe/bike_cafe.json index 111a4bc28..3619c7068 100644 --- a/assets/layers/bike_cafe/bike_cafe.json +++ b/assets/layers/bike_cafe/bike_cafe.json @@ -1,344 +1,352 @@ { - "id": "bike_cafe", - "name": { - "en": "Bike cafe", - "nl": "Fietscafé", - "fr": "Café vélo", - "gl": "Café de ciclistas", - "de": "Fahrrad-Café", - "it": "Caffè in bici", - "zh_Hans": "自行车咖啡", - "ru": "Велосипедное кафе", - "zh_Hant": "單車咖啡廳", - "pt_BR": "Café de bicicletas" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "amenity=pub", - "amenity=bar", - "amenity=cafe", - "amenity=restaurant" - ] - }, - { - "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", - "or": [ - "pub=cycling", - "pub=bicycle", - "theme=cycling", - "theme=bicycle", - "service:bicycle:.*~~*" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Bike cafe", - "nl": "Fietscafé", - "fr": "Café Vélo", - "gl": "Café de ciclistas", - "de": "Fahrrad-Café", - "it": "Caffè in bici", - "zh_Hans": "自行车咖啡", - "ru": "Велосипедное кафе", - "zh_Hant": "單車咖啡廳", - "pt_BR": "Café de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bike cafe {name}", - "nl": "Fietscafé {name}", - "fr": "Café Vélo {name}", - "gl": "Café de ciclistas {name}", - "de": "Fahrrad-Café {name}", - "it": "Caffè in bici {name}", - "zh_Hans": "自行车咖啡 {name}", - "ru": "Велосипедное кафе {name}", - "zh_Hant": "單車咖啡廳{name}", - "pt_BR": "Café de bicicleta {name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "What is the name of this bike cafe?", - "nl": "Wat is de naam van dit fietscafé?", - "fr": "Quel est le nom de ce Café vélo ?", - "gl": "Cal é o nome deste café de ciclistas?", - "de": "Wie heißt dieses Fahrrad-Café?", - "it": "Qual è il nome di questo caffè in bici?", - "zh_Hans": "这个自行车咖啡的名字是什么?", - "ru": "Как называется это байк-кафе?", - "zh_Hant": "這個單車咖啡廳的名稱是?", - "pt_BR": "Qual o nome deste café de bicicleta?" - }, - "render": { - "en": "This bike cafe is called {name}", - "nl": "Dit fietscafé heet {name}", - "fr": "Ce Café vélo s'appelle {name}", - "gl": "Este café de ciclistas chámase {name}", - "de": "Dieses Fahrrad-Café heißt {name}", - "it": "Questo caffè in bici è chiamato {name}", - "zh_Hans": "这家自行车咖啡叫做 {name}", - "ru": "Это велосипедное кафе называется {name}", - "zh_Hant": "這個單車咖啡廳叫做 {name}", - "pt_BR": "Este café de bicicleta se chama {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "question": { - "en": "Does this bike cafe offer a bike pump for use by anyone?", - "nl": "Biedt dit fietscafé een fietspomp aan voor iedereen?", - "fr": "Est-ce que ce Café vélo propose une pompe en libre accès ?", - "gl": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?", - "de": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?", - "it": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?", - "zh_Hans": "这家自行车咖啡为每个使用者提供打气筒吗?", - "ru": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?", - "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" - }, - "mappings": [ - { - "if": "service:bicycle:pump=yes", - "then": { - "en": "This bike cafe offers a bike pump for anyone", - "nl": "Dit fietscafé biedt een fietspomp aan voor eender wie", - "fr": "Ce Café vélo offre une pompe en libre accès", - "gl": "Este café de ciclistas ofrece unha bomba de ar", - "de": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann", - "it": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile", - "zh_Hans": "这家自行车咖啡为每个人提供打气筒", - "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬", - "ru": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" - } - }, - { - "if": "service:bicycle:pump=no", - "then": { - "en": "This bike cafe doesn't offer a bike pump for anyone", - "nl": "Dit fietscafé biedt geen fietspomp aan voor iedereen", - "fr": "Ce Café vélo n'offre pas de pompe en libre accès", - "gl": "Este café de ciclistas non ofrece unha bomba de ar", - "de": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann", - "it": "Questo caffè in bici non offre una pompa per bici liberamente utilizzabile", - "zh_Hans": "这家自行车咖啡不为每个人提供打气筒", - "zh_Hant": "這個單車咖啡廳並沒有為所有人提供單車打氣甬", - "ru": "В этом велосипедном кафе нет велосипедного насоса для всеобщего использования" - } - } - ] - }, - { - "question": { - "en": "Are there tools here to repair your own bike?", - "nl": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?", - "fr": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", - "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", - "it": "Ci sono degli strumenti per riparare la propria bicicletta?", - "zh_Hans": "这里有供你修车用的工具吗?", - "zh_Hant": "這裡是否有工具修理你的單車嗎?", - "ru": "Есть ли здесь инструменты для починки вашего велосипеда?", - "pt_BR": "Há ferramentas aqui para consertar sua bicicleta?" - }, - "mappings": [ - { - "if": "service:bicycle:diy=yes", - "then": { - "en": "This bike cafe offers tools for DIY repair", - "nl": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce Café vélo propose des outils pour réparer son vélo soi-même", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an", - "it": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te", - "zh_Hans": "这家自行车咖啡为DIY修理者提供工具", - "zh_Hant": "這個單車咖啡廳提供工具讓你修理", - "ru": "В этом велосипедном кафе есть инструменты для починки своего велосипеда", - "pt_BR": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" - } - }, - { - "if": "service:bicycle:diy=no", - "then": { - "en": "This bike cafe doesn't offer tools for DIY repair", - "nl": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même", - "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an", - "it": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te", - "zh_Hans": "这家自行车咖啡不为DIY修理者提供工具", - "zh_Hant": "這個單車咖啡廳並沒有提供工具讓你修理", - "ru": "В этом велосипедном кафе нет инструментов для починки своего велосипеда", - "pt_BR": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" - } - } - ] - }, - { - "question": { - "en": "Does this bike cafe repair bikes?", - "nl": "Herstelt dit fietscafé fietsen?", - "fr": "Est-ce que ce Café vélo répare les vélos ?", - "gl": "Este café de ciclistas arranxa bicicletas?", - "de": "Repariert dieses Fahrrad-Café Fahrräder?", - "it": "Questo caffè in bici ripara le bici?", - "zh_Hans": "这家自行车咖啡t提供修车服务吗?", - "zh_Hant": "這個單車咖啡廳是否能修理單車?", - "ru": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?", - "pt_BR": "Este café de bicicleta conserta bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:repair=yes", - "then": { - "en": "This bike cafe repairs bikes", - "nl": "Dit fietscafé herstelt fietsen", - "fr": "Ce Café vélo répare les vélos", - "gl": "Este café de ciclistas arranxa bicicletas", - "de": "Dieses Fahrrad-Café repariert Fahrräder", - "it": "Questo caffè in bici ripara le bici", - "zh_Hans": "这家自行车咖啡可以修车", - "zh_Hant": "這個單車咖啡廳修理單車", - "ru": "В этом велосипедном кафе есть услуги ремонта велосипедов", - "pt_BR": "Este café de bicicleta conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=no", - "then": { - "en": "This bike cafe doesn't repair bikes", - "nl": "Dit fietscafé herstelt geen fietsen", - "fr": "Ce Café vélo ne répare pas les vélos", - "gl": "Este café de ciclistas non arranxa bicicletas", - "de": "Dieses Fahrrad-Café repariert keine Fahrräder", - "it": "Questo caffè in bici non ripara le bici", - "zh_Hans": "这家自行车咖啡不能修车", - "zh_Hant": "這個單車咖啡廳並不修理單車", - "ru": "В этом велосипедном кафе нет услуг ремонта велосипедов", - "pt_BR": "Este café de bicicleta não conserta bicicletas" - } - } - ] - }, - { - "question": { - "en": "What is the website of {name}?", - "nl": "Wat is de website van {name}?", - "fr": "Quel est le site web de {name} ?", - "gl": "Cal é a páxina web de {name}?", - "de": "Was ist die Webseite von {name}?", - "it": "Qual è il sito web di {name}?", - "ru": "Какой сайт у {name}?", - "zh_Hans": "{name}的网站是什么?", - "zh_Hant": "{name} 的網站是?", - "pt_BR": "Qual o website de {name}?" - }, - "render": "{website}", - "freeform": { - "key": "website" - } - }, - { - "question": { - "en": "What is the phone number of {name}?", - "nl": "Wat is het telefoonnummer van {name}?", - "fr": "Quel est le numéro de téléphone de {name} ?", - "gl": "Cal é o número de teléfono de {name}?", - "de": "Wie lautet die Telefonnummer von {name}?", - "it": "Qual è il numero di telefono di {name}?", - "ru": "Какой номер телефона у {name}?", - "zh_Hans": "{name}的电话号码是什么?", - "zh_Hant": "{name} 的電話號碼是?", - "pt_BR": "Qual o número de telefone de {name}?" - }, - "render": "{phone}", - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "en": "What is the email address of {name}?", - "nl": "Wat is het email-adres van {name}?", - "fr": "Quelle est l'adresse électronique de {name} ?", - "gl": "Cal é o enderezo de correo electrónico de {name}?", - "de": "Wie lautet die E-Mail-Adresse von {name}?", - "it": "Qual è l’indirizzo email di {name}?", - "ru": "Какой адрес электронной почты у {name}?", - "zh_Hans": "{name}的电子邮箱是什么?", - "zh_Hant": "{name} 的電子郵件地址是?", - "pt_BR": "Qual o endereço de email de {name}?" - }, - "render": "{email}", - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "question": { - "en": "When it this bike café opened?", - "nl": "Wanneer is dit fietscafé geopend?", - "fr": "Quand ce Café vélo est-t-il ouvert ?", - "it": "Quando è aperto questo caffè in bici?", - "zh_Hans": "这家自行车咖啡什么时候开门营业?", - "zh_Hant": "何時這個單車咖啡廳營運?", - "ru": "Каков режим работы этого велосипедного кафе?", - "pt_BR": "Quando este café de bicicleta abre?" - }, - "render": "{opening_hours_table(opening_hours)}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - } - } - ], - "icon": { - "render": "./assets/layers/bike_cafe/bike_cafe.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#694E2D" - }, - "presets": [ - { - "title": { + "id": "bike_cafe", + "name": { "en": "Bike cafe", "nl": "Fietscafé", - "fr": "Café Vélo", + "fr": "Café vélo", "gl": "Café de ciclistas", "de": "Fahrrad-Café", "it": "Caffè in bici", "zh_Hans": "自行车咖啡", - "zh_Hant": "單車咖啡廳", "ru": "Велосипедное кафе", - "pt_BR": "Café de bicicleta" - }, - "tags": [ - "amenity=pub", - "pub=cycling" - ] - } - ], - "wayHandling": 2 + "zh_Hant": "單車咖啡廳", + "pt_BR": "Café de bicicletas" + }, + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "amenity=pub", + "amenity=bar", + "amenity=cafe", + "amenity=restaurant" + ] + }, + { + "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", + "or": [ + "pub=cycling", + "pub=bicycle", + "theme=cycling", + "theme=bicycle", + "service:bicycle:.*~~*" + ] + } + ] + } + }, + "title": { + "render": { + "en": "Bike cafe", + "nl": "Fietscafé", + "fr": "Café Vélo", + "gl": "Café de ciclistas", + "de": "Fahrrad-Café", + "it": "Caffè in bici", + "zh_Hans": "自行车咖啡", + "ru": "Велосипедное кафе", + "zh_Hant": "單車咖啡廳", + "pt_BR": "Café de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Bike cafe {name}", + "nl": "Fietscafé {name}", + "fr": "Café Vélo {name}", + "gl": "Café de ciclistas {name}", + "de": "Fahrrad-Café {name}", + "it": "Caffè in bici {name}", + "zh_Hans": "自行车咖啡 {name}", + "ru": "Велосипедное кафе {name}", + "zh_Hant": "單車咖啡廳{name}", + "pt_BR": "Café de bicicleta {name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "What is the name of this bike cafe?", + "nl": "Wat is de naam van dit fietscafé?", + "fr": "Quel est le nom de ce Café vélo ?", + "gl": "Cal é o nome deste café de ciclistas?", + "de": "Wie heißt dieses Fahrrad-Café?", + "it": "Qual è il nome di questo caffè in bici?", + "zh_Hans": "这个自行车咖啡的名字是什么?", + "ru": "Как называется это байк-кафе?", + "zh_Hant": "這個單車咖啡廳的名稱是?", + "pt_BR": "Qual o nome deste café de bicicleta?" + }, + "render": { + "en": "This bike cafe is called {name}", + "nl": "Dit fietscafé heet {name}", + "fr": "Ce Café vélo s'appelle {name}", + "gl": "Este café de ciclistas chámase {name}", + "de": "Dieses Fahrrad-Café heißt {name}", + "it": "Questo caffè in bici è chiamato {name}", + "zh_Hans": "这家自行车咖啡叫做 {name}", + "ru": "Это велосипедное кафе называется {name}", + "zh_Hant": "這個單車咖啡廳叫做 {name}", + "pt_BR": "Este café de bicicleta se chama {name}" + }, + "freeform": { + "key": "name" + }, + "id": "bike_cafe-name" + }, + { + "id": "bike_cafe-bike-pump", + "question": { + "en": "Does this bike cafe offer a bike pump for use by anyone?", + "nl": "Biedt dit fietscafé een fietspomp aan voor iedereen?", + "fr": "Est-ce que ce Café vélo propose une pompe en libre accès ?", + "gl": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?", + "de": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?", + "it": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?", + "zh_Hans": "这家自行车咖啡为每个使用者提供打气筒吗?", + "ru": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?", + "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" + }, + "mappings": [ + { + "if": "service:bicycle:pump=yes", + "then": { + "en": "This bike cafe offers a bike pump for anyone", + "nl": "Dit fietscafé biedt een fietspomp aan voor eender wie", + "fr": "Ce Café vélo offre une pompe en libre accès", + "gl": "Este café de ciclistas ofrece unha bomba de ar", + "de": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann", + "it": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile", + "zh_Hans": "这家自行车咖啡为每个人提供打气筒", + "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬", + "ru": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" + } + }, + { + "if": "service:bicycle:pump=no", + "then": { + "en": "This bike cafe doesn't offer a bike pump for anyone", + "nl": "Dit fietscafé biedt geen fietspomp aan voor iedereen", + "fr": "Ce Café vélo n'offre pas de pompe en libre accès", + "gl": "Este café de ciclistas non ofrece unha bomba de ar", + "de": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann", + "it": "Questo caffè in bici non offre una pompa per bici liberamente utilizzabile", + "zh_Hans": "这家自行车咖啡不为每个人提供打气筒", + "zh_Hant": "這個單車咖啡廳並沒有為所有人提供單車打氣甬", + "ru": "В этом велосипедном кафе нет велосипедного насоса для всеобщего использования" + } + } + ] + }, + { + "id": "bike_cafe-repair-tools", + "question": { + "en": "Are there tools here to repair your own bike?", + "nl": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?", + "fr": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", + "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", + "it": "Ci sono degli strumenti per riparare la propria bicicletta?", + "zh_Hans": "这里有供你修车用的工具吗?", + "zh_Hant": "這裡是否有工具修理你的單車嗎?", + "ru": "Есть ли здесь инструменты для починки вашего велосипеда?", + "pt_BR": "Há ferramentas aqui para consertar sua bicicleta?" + }, + "mappings": [ + { + "if": "service:bicycle:diy=yes", + "then": { + "en": "This bike cafe offers tools for DIY repair", + "nl": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce Café vélo propose des outils pour réparer son vélo soi-même", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an", + "it": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te", + "zh_Hans": "这家自行车咖啡为DIY修理者提供工具", + "zh_Hant": "這個單車咖啡廳提供工具讓你修理", + "ru": "В этом велосипедном кафе есть инструменты для починки своего велосипеда", + "pt_BR": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" + } + }, + { + "if": "service:bicycle:diy=no", + "then": { + "en": "This bike cafe doesn't offer tools for DIY repair", + "nl": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même", + "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an", + "it": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te", + "zh_Hans": "这家自行车咖啡不为DIY修理者提供工具", + "zh_Hant": "這個單車咖啡廳並沒有提供工具讓你修理", + "ru": "В этом велосипедном кафе нет инструментов для починки своего велосипеда", + "pt_BR": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" + } + } + ] + }, + { + "id": "bike_cafe-repair-service", + "question": { + "en": "Does this bike cafe repair bikes?", + "nl": "Herstelt dit fietscafé fietsen?", + "fr": "Est-ce que ce Café vélo répare les vélos ?", + "gl": "Este café de ciclistas arranxa bicicletas?", + "de": "Repariert dieses Fahrrad-Café Fahrräder?", + "it": "Questo caffè in bici ripara le bici?", + "zh_Hans": "这家自行车咖啡t提供修车服务吗?", + "zh_Hant": "這個單車咖啡廳是否能修理單車?", + "ru": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?", + "pt_BR": "Este café de bicicleta conserta bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:repair=yes", + "then": { + "en": "This bike cafe repairs bikes", + "nl": "Dit fietscafé herstelt fietsen", + "fr": "Ce Café vélo répare les vélos", + "gl": "Este café de ciclistas arranxa bicicletas", + "de": "Dieses Fahrrad-Café repariert Fahrräder", + "it": "Questo caffè in bici ripara le bici", + "zh_Hans": "这家自行车咖啡可以修车", + "zh_Hant": "這個單車咖啡廳修理單車", + "ru": "В этом велосипедном кафе есть услуги ремонта велосипедов", + "pt_BR": "Este café de bicicleta conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=no", + "then": { + "en": "This bike cafe doesn't repair bikes", + "nl": "Dit fietscafé herstelt geen fietsen", + "fr": "Ce Café vélo ne répare pas les vélos", + "gl": "Este café de ciclistas non arranxa bicicletas", + "de": "Dieses Fahrrad-Café repariert keine Fahrräder", + "it": "Questo caffè in bici non ripara le bici", + "zh_Hans": "这家自行车咖啡不能修车", + "zh_Hant": "這個單車咖啡廳並不修理單車", + "ru": "В этом велосипедном кафе нет услуг ремонта велосипедов", + "pt_BR": "Este café de bicicleta não conserta bicicletas" + } + } + ] + }, + { + "question": { + "en": "What is the website of {name}?", + "nl": "Wat is de website van {name}?", + "fr": "Quel est le site web de {name} ?", + "gl": "Cal é a páxina web de {name}?", + "de": "Was ist die Webseite von {name}?", + "it": "Qual è il sito web di {name}?", + "ru": "Какой сайт у {name}?", + "zh_Hans": "{name}的网站是什么?", + "zh_Hant": "{name} 的網站是?", + "pt_BR": "Qual o website de {name}?" + }, + "render": "{website}", + "freeform": { + "key": "website" + }, + "id": "bike_cafe-website" + }, + { + "question": { + "en": "What is the phone number of {name}?", + "nl": "Wat is het telefoonnummer van {name}?", + "fr": "Quel est le numéro de téléphone de {name} ?", + "gl": "Cal é o número de teléfono de {name}?", + "de": "Wie lautet die Telefonnummer von {name}?", + "it": "Qual è il numero di telefono di {name}?", + "ru": "Какой номер телефона у {name}?", + "zh_Hans": "{name}的电话号码是什么?", + "zh_Hant": "{name} 的電話號碼是?", + "pt_BR": "Qual o número de telefone de {name}?" + }, + "render": "{phone}", + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "bike_cafe-phone" + }, + { + "question": { + "en": "What is the email address of {name}?", + "nl": "Wat is het email-adres van {name}?", + "fr": "Quelle est l'adresse électronique de {name} ?", + "gl": "Cal é o enderezo de correo electrónico de {name}?", + "de": "Wie lautet die E-Mail-Adresse von {name}?", + "it": "Qual è l’indirizzo email di {name}?", + "ru": "Какой адрес электронной почты у {name}?", + "zh_Hans": "{name}的电子邮箱是什么?", + "zh_Hant": "{name} 的電子郵件地址是?", + "pt_BR": "Qual o endereço de email de {name}?" + }, + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + }, + "id": "bike_cafe-email" + }, + { + "question": { + "en": "When it this bike café opened?", + "nl": "Wanneer is dit fietscafé geopend?", + "fr": "Quand ce Café vélo est-t-il ouvert ?", + "it": "Quando è aperto questo caffè in bici?", + "zh_Hans": "这家自行车咖啡什么时候开门营业?", + "zh_Hant": "何時這個單車咖啡廳營運?", + "ru": "Каков режим работы этого велосипедного кафе?", + "pt_BR": "Quando este café de bicicleta abre?" + }, + "render": "{opening_hours_table(opening_hours)}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "id": "bike_cafe-opening_hours" + } + ], + "icon": { + "render": "./assets/layers/bike_cafe/bike_cafe.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#694E2D" + }, + "presets": [ + { + "title": { + "en": "Bike cafe", + "nl": "Fietscafé", + "fr": "Café Vélo", + "gl": "Café de ciclistas", + "de": "Fahrrad-Café", + "it": "Caffè in bici", + "zh_Hans": "自行车咖啡", + "zh_Hant": "單車咖啡廳", + "ru": "Велосипедное кафе", + "pt_BR": "Café de bicicleta" + }, + "tags": [ + "amenity=pub", + "pub=cycling" + ] + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bike_cleaning/bike_cleaning.json b/assets/layers/bike_cleaning/bike_cleaning.json index d4c45d6a7..6c76d519b 100644 --- a/assets/layers/bike_cleaning/bike_cleaning.json +++ b/assets/layers/bike_cleaning/bike_cleaning.json @@ -1,57 +1,6 @@ { - "id": "bike_cleaning", - "name": { - "en": "Bike cleaning service", - "nl": "Fietsschoonmaakpunt", - "fr": "Service de nettoyage de vélo", - "it": "Servizio lavaggio bici", - "de": "Fahrrad-Reinigungsdienst", - "zh_Hant": "單車清理服務", - "pt_BR": "Serviço de limpeza de bicicletas" - }, - "title": { - "render": { - "en": "Bike cleaning service", - "nl": "Fietsschoonmaakpunt", - "fr": "Service de nettoyage de vélo", - "it": "Servizio lavaggio bici", - "de": "Fahrrad-Reinigungsdienst", - "zh_Hant": "單車清理服務", - "pt_BR": "Serviço de limpeza de bicicletas" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bike cleaning service {name}", - "nl": "Fietsschoonmaakpunt {name}", - "fr": "Service de nettoyage de vélo {name}", - "it": "Servizio lavaggio bici {name}", - "de": "Fahrrad-Reinigungsdienst{name}", - "zh_Hant": "單車清理服務 {name}", - "pt_BR": "Serviço de limpeza de bicicletas {name}" - } - } - ] - }, - "icon": { - "render": "./assets/layers/bike_cleaning/bike_cleaning.svg" - }, - "iconSize": "50,50,bottom", - "source": { - "osmTags": { - "or": [ - "service:bicycle:cleaning=yes", - "service:bicycle:cleaning=diy", - "amenity=bicycle_wash" - ] - } - }, - "minzoom": 13, - "wayHandling": 1, - "presets": [ - { - "title": { + "id": "bike_cleaning", + "name": { "en": "Bike cleaning service", "nl": "Fietsschoonmaakpunt", "fr": "Service de nettoyage de vélo", @@ -59,89 +8,142 @@ "de": "Fahrrad-Reinigungsdienst", "zh_Hant": "單車清理服務", "pt_BR": "Serviço de limpeza de bicicletas" - }, - "tags": [ - "amenity=bicycle_wash" - ] - } - ], - "color": "#6bc4f7", - "iconOverlays": [ - { - "if": { - "and": [ - "service:bicycle:cleaning~*", - "amenity!=bike_wash" - ] - }, - "then": { - "render": "./assets/layers/bike_cleaning/bike_cleaning_icon.svg", - "roaming": true - }, - "badge": true - } - ], - "titleIcons": [ - { - "render": "", - "roaming": true - } - ], - "tagRenderings": [ - "images", - { - "question": "How much does it cost to use the cleaning service?", - "render": "Using the cleaning service costs {charge}", - "condition": "amenity!=bike_wash", - "freeform": { - "key": "service:bicycle:cleaning:charge", - "addExtraTags": [ - "service:bicycle:cleaning:fee=yes" - ] - }, - "mappings": [ - { - "if": "service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge=", - "then": "The cleaning service is free to use" - }, - { - "if": "service:bicycle:cleaning:fee=no&", - "then": "Free to use", - "hideInAnswer": true - }, - { - "if": "service:bicycle:cleaning:fee=yes", - "then": "The cleaning service has a fee" - } - ], - "roaming": true }, - { - "question": "How much does it cost to use the cleaning service?", - "render": "Using the cleaning service costs {charge}", - "condition": "amenity=bike_wash", - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" + "title": { + "render": { + "en": "Bike cleaning service", + "nl": "Fietsschoonmaakpunt", + "fr": "Service de nettoyage de vélo", + "it": "Servizio lavaggio bici", + "de": "Fahrrad-Reinigungsdienst", + "zh_Hant": "單車清理服務", + "pt_BR": "Serviço de limpeza de bicicletas" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Bike cleaning service {name}", + "nl": "Fietsschoonmaakpunt {name}", + "fr": "Service de nettoyage de vélo {name}", + "it": "Servizio lavaggio bici {name}", + "de": "Fahrrad-Reinigungsdienst{name}", + "zh_Hant": "單車清理服務 {name}", + "pt_BR": "Serviço de limpeza de bicicletas {name}" + } + } ] - }, - "mappings": [ - { - "if": "fee=no&charge=", - "then": "Free to use cleaning service" - }, - { - "if": "fee=no&", - "then": "Free to use", - "hideInAnswer": true - }, - { - "if": "fee=yes", - "then": "The cleaning service has a fee" + }, + "icon": { + "render": "./assets/layers/bike_cleaning/bike_cleaning.svg" + }, + "iconSize": "50,50,bottom", + "source": { + "osmTags": { + "or": [ + "service:bicycle:cleaning=yes", + "service:bicycle:cleaning=diy", + "amenity=bicycle_wash" + ] } - ], - "roaming": false - } - ] + }, + "minzoom": 13, + "wayHandling": 1, + "presets": [ + { + "title": { + "en": "Bike cleaning service", + "nl": "Fietsschoonmaakpunt", + "fr": "Service de nettoyage de vélo", + "it": "Servizio lavaggio bici", + "de": "Fahrrad-Reinigungsdienst", + "zh_Hant": "單車清理服務", + "pt_BR": "Serviço de limpeza de bicicletas" + }, + "tags": [ + "amenity=bicycle_wash" + ] + } + ], + "color": "#6bc4f7", + "iconOverlays": [ + { + "if": { + "and": [ + "service:bicycle:cleaning~*", + "amenity!=bike_wash" + ] + }, + "then": { + "render": "./assets/layers/bike_cleaning/bike_cleaning_icon.svg", + "roaming": true + }, + "badge": true + } + ], + "titleIcons": [ + { + "render": "", + "roaming": true + } + ], + "tagRenderings": [ + "images", + { + "question": "How much does it cost to use the cleaning service?", + "render": "Using the cleaning service costs {charge}", + "condition": "amenity!=bike_wash", + "freeform": { + "key": "service:bicycle:cleaning:charge", + "addExtraTags": [ + "service:bicycle:cleaning:fee=yes" + ] + }, + "mappings": [ + { + "if": "service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge=", + "then": "The cleaning service is free to use" + }, + { + "if": "service:bicycle:cleaning:fee=no&", + "then": "Free to use", + "hideInAnswer": true + }, + { + "if": "service:bicycle:cleaning:fee=yes", + "then": "The cleaning service has a fee" + } + ], + "roaming": true, + "id": "bike_cleaning-service:bicycle:cleaning:charge" + }, + { + "question": "How much does it cost to use the cleaning service?", + "render": "Using the cleaning service costs {charge}", + "condition": "amenity=bike_wash", + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": "fee=no&charge=", + "then": "Free to use cleaning service" + }, + { + "if": "fee=no&", + "then": "Free to use", + "hideInAnswer": true + }, + { + "if": "fee=yes", + "then": "The cleaning service has a fee" + } + ], + "roaming": false, + "id": "bike_cleaning-charge" + } + ] } \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/bike_monitoring_station.json b/assets/layers/bike_monitoring_station/bike_monitoring_station.json deleted file mode 100644 index 702e1690e..000000000 --- a/assets/layers/bike_monitoring_station/bike_monitoring_station.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "id": "bike_monitoring_station", - "name": { - "en": "Monitoring stations", - "nl": "Telstation", - "fr": "Stations de contrôle", - "it": "Stazioni di monitoraggio", - "zh_Hant": "監視站", - "ru": "Станции мониторинга", - "pt_BR": "Estações de monitoramento" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=monitoring_station", - "monitoring:bicycle=yes" - ] - } - }, - "title": { - "render": { - "nl": "Fietstelstation", - "en": "Bicycle counting station", - "fr": "Station de comptage de vélo", - "it": "Contabiciclette", - "de": "Fahrradzählstation", - "zh_Hant": "單車計數站", - "pt_BR": "Estação de contagem de bicicletas" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bicycle counting station {name}", - "nl": "Fietstelstation {name}", - "fr": "Station de comptage de vélo {name}", - "it": "Contabiciclette {name}", - "de": "Fahrradzählstation {name}", - "zh_Hant": "單車計數站 {name}", - "pl": "Stacja liczenia rowerów {name}", - "pt_BR": "Estação de contagem de bicicletas {name}" - } - }, - { - "if": "ref~*", - "then": { - "en": "Bicycle counting station {ref}", - "nl": "Fietstelstation {ref}", - "fr": "Station de comptage de vélo {ref}", - "it": "Contabiciclette {ref}", - "de": "Fahrradzählstation {ref}", - "zh_Hant": "單車計數站 {ref}", - "pl": "Stacja liczenia rowerów {ref}", - "pt_BR": "Estação de contagem de bicicletas {ref}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": "{live({url},{url:format},hour)} cyclists last hour
{live({url},{url:format},day)} cyclists today
{live({url},{url:format},year)} cyclists this year
", - "condition": { - "and": [ - "url~*", - "url:format~*" - ] - } - } - ], - "icon": { - "render": "./assets/layers/bike_monitoring_station/monitoring_station.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [] -} \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/license_info.json b/assets/layers/bike_monitoring_station/license_info.json deleted file mode 100644 index 45abb1c69..000000000 --- a/assets/layers/bike_monitoring_station/license_info.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "path": "monitoring_station.svg", - "license": "CC-BY-SA 3.0", - "authors": [ - "Fabián Alexis" - ], - "sources": [ - "https://commons.wikimedia.org/wiki/File:Antu_chronometer-reset.svg" - ] - } -] \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/monitoring_station.svg b/assets/layers/bike_monitoring_station/monitoring_station.svg deleted file mode 100644 index a780b4ea8..000000000 --- a/assets/layers/bike_monitoring_station/monitoring_station.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/layers/bike_parking/bike_parking.json b/assets/layers/bike_parking/bike_parking.json index e1983de68..049bcac9e 100644 --- a/assets/layers/bike_parking/bike_parking.json +++ b/assets/layers/bike_parking/bike_parking.json @@ -1,36 +1,6 @@ { - "id": "bike_parking", - "name": { - "en": "Bike parking", - "nl": "Fietsparking", - "fr": "Parking à vélo", - "gl": "Aparcadoiro de bicicletas", - "de": "Fahrrad-Parkplätze", - "hu": "Kerékpáros parkoló", - "it": "Parcheggio bici", - "zh_Hant": "單車停車場", - "ru": "Велопарковка", - "pl": "Parking dla rowerów", - "pt_BR": "Estacionamento de bicicletas" - }, - "minzoom": 17, - "source": { - "osmTags": { - "and": [ - "amenity=bicycle_parking" - ] - } - }, - "icon": { - "render": "./assets/layers/bike_parking/parking.svg" - }, - "iconSize": "40,40,bottom", - "color": "#00f", - "width": "1", - "wayHandling": 2, - "presets": [ - { - "title": { + "id": "bike_parking", + "name": { "en": "Bike parking", "nl": "Fietsparking", "fr": "Parking à vélo", @@ -42,471 +12,501 @@ "ru": "Велопарковка", "pl": "Parking dla rowerów", "pt_BR": "Estacionamento de bicicletas" - }, - "tags": [ - "amenity=bicycle_parking" - ] - } - ], - "title": { - "render": { - "en": "Bike parking", - "nl": "Fietsparking", - "fr": "Parking à vélo", - "gl": "Aparcadoiro de bicicletas", - "de": "Fahrrad-Parkplätze", - "hu": "Kerékpáros parkoló", - "it": "Parcheggio bici", - "zh_Hant": "單車停車場", - "ru": "Велопарковка", - "pl": "Parking dla rowerów", - "pt_BR": "Estacionamento de bicicletas" - } - }, - "tagRenderings": [ - "images", - { - "#": "Bicycle parking type", - "question": { - "en": "What is the type of this bicycle parking?", - "nl": "Van welk type is deze fietsparking?", - "fr": "Quel type de parking à vélos est-ce ?", - "gl": "Que tipo de aparcadoiro de bicicletas é?", - "de": "Was ist die Art dieses Fahrrad-Parkplatzes?", - "hu": "Milyen típusú ez a kerékpáros parkoló?", - "it": "Di che tipo di parcheggio bici si tratta?", - "ru": "К какому типу относится эта велопарковка?", - "zh_Hant": "這是那種類型的單車停車場?", - "pl": "Jaki jest typ tego parkingu dla rowerów?", - "pt_BR": "Qual o tipo deste estacionamento de bicicletas?" - }, - "render": { - "en": "This is a bicycle parking of the type: {bicycle_parking}", - "nl": "Dit is een fietsparking van het type: {bicycle_parking}", - "fr": "Ceci est un parking à vélo de type {bicycle_parking}", - "gl": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}", - "de": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}", - "hu": "Ez egy {bicycle_parking} típusú kerékpáros parkoló", - "it": "È un parcheggio bici del tipo: {bicycle_parking}", - "zh_Hant": "這個單車停車場的類型是:{bicycle_parking}", - "ru": "Это велопарковка типа {bicycle_parking}", - "pl": "Jest to parking rowerowy typu: {bicycle_parking}", - "pt_BR": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" - }, - "freeform": { - "key": "bicycle_parking", - "addExtraTags": [ - "fixme=Freeform used on 'bicycle_parking'-tag: possibly a wrong value" - ] - }, - "mappings": [ - { - "if": "bicycle_parking=stands", - "then": { - "en": "Staple racks ", - "nl": "Nietjes ", - "fr": "Arceaux ", - "gl": "De roda (Stands) ", - "de": "Fahrradbügel ", - "hu": "\"U\" ", - "it": "Archetti ", - "zh_Hant": "單車架 " - } - }, - { - "if": "bicycle_parking=wall_loops", - "then": { - "en": "Wheel rack/loops ", - "nl": "Wielrek/lussen ", - "fr": "Pinces-roues ", - "gl": "Aros ", - "de": "Metallgestänge ", - "hu": "Kengyeles ", - "it": "Scolapiatti ", - "zh_Hant": "車輪架/圓圈 " - } - }, - { - "if": "bicycle_parking=handlebar_holder", - "then": { - "en": "Handlebar holder ", - "nl": "Stuurhouder ", - "fr": "Support guidon ", - "gl": "Cadeado para guiador ", - "de": "Halter für Fahrradlenker ", - "it": "Blocca manubrio ", - "zh_Hant": "車把架 " - } - }, - { - "if": "bicycle_parking=rack", - "then": { - "en": "Rack ", - "nl": "Rek ", - "fr": "Râtelier ", - "gl": "Cremalleira ", - "de": "Gestell ", - "zh_Hant": "車架", - "it": "Rastrelliera ", - "ru": "Стойка " - } - }, - { - "if": "bicycle_parking=two_tier", - "then": { - "en": "Two-tiered ", - "nl": "Dubbel (twee verdiepingen) ", - "fr": "Superposé ", - "gl": "Dobre cremalleira ", - "de": "Zweistufig ", - "hu": "Kétszintű ", - "zh_Hant": "兩層", - "it": "A due piani ", - "ru": "Двухуровневая " - } - }, - { - "if": "bicycle_parking=shed", - "then": { - "en": "Shed ", - "nl": "Schuur ", - "fr": "Abri ", - "gl": "Abeiro ", - "de": "Schuppen ", - "hu": "Fészer ", - "zh_Hant": "車棚 ", - "it": "Rimessa ", - "ru": "Навес " - } - }, - { - "if": "bicycle_parking=bollard", - "then": { - "en": "Bollard ", - "nl": "Paal met ring ", - "fr": "Potelet ", - "it": "Colonnina ", - "de": "Poller ", - "zh_Hant": "柱子 " - } - }, - { - "if": "bicycle_parking=floor", - "then": { - "en": "An area on the floor which is marked for bicycle parking", - "nl": "Een oppervlakte die gemarkeerd is om fietsen te parkeren", - "fr": "Zone au sol qui est marquée pour le stationnement des vélos", - "it": "Una zona del pavimento che è marcata per il parcheggio delle bici", - "de": "Ein Bereich auf dem Boden, der für das Abstellen von Fahrrädern gekennzeichnet ist", - "zh_Hant": "樓層當中標示為單車停車場的區域" - } + }, + "minzoom": 17, + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_parking" + ] } - ] }, - { - "#": "Underground?", - "question": { - "en": "What is the relative location of this bicycle parking?", - "nl": "Wat is de relatieve locatie van deze parking??", - "fr": "Quelle est la position relative de ce parking à vélo ?", - "it": "Qual è la posizione relativa di questo parcheggio bici?", - "zh_Hant": "這個單車停車場的相對位置是?", - "pl": "Jaka jest względna lokalizacja tego parkingu rowerowego?", - "pt_BR": "Qual a localização relativa deste estacionamento de bicicletas?" - }, - "mappings": [ + "icon": { + "render": "./assets/layers/bike_parking/parking.svg" + }, + "iconSize": "40,40,bottom", + "color": "#00f", + "width": "1", + "wayHandling": 2, + "presets": [ { - "if": "location=underground", - "then": { - "en": "Underground parking", - "nl": "Ondergrondse parking", - "fr": "Parking souterrain", - "it": "Parcheggio sotterraneo", - "ru": "Подземная парковка", - "de": "Tiefgarage", - "zh_Hant": "地下停車場", - "pt_BR": "Estacionamento subterrâneo" - } - }, - { - "if": "location=underground", - "then": { - "en": "Underground parking", - "nl": "Ondergrondse parking", - "fr": "Parking souterrain", - "it": "Parcheggio sotterraneo", - "ru": "Подземная парковка", - "de": "Tiefgarage", - "zh_Hant": "地下停車場", - "pt_BR": "Estacionamento subterrâneo" - } - }, - { - "if": "location=surface", - "then": { - "en": "Surface level parking", - "nl": "Parking op de begane grond", - "fr": "Parking en surface", - "hu": "Felszíni parkoló", - "it": "Parcheggio in superficie", - "de": "Ebenerdiges Parken", - "zh_Hant": "地面停車場", - "pt_BR": "Estacionamento de superfície" - } - }, - { - "if": "location=", - "then": { - "en": "Surface level parking", - "nl": "Parking op de begane grond", - "fr": "Parking en surface", - "hu": "Felszíni parkoló", - "it": "Parcheggio in superficie", - "de": "Ebenerdiges Parken", - "zh_Hant": "地面層停車場", - "pt_BR": "Estacionamento ao nível da superfície" - }, - "hideInAnwser": true - }, - { - "if": "location=rooftop", - "then": { - "en": "Rooftop parking", - "nl": "Dakparking", - "fr": "Parking sur un toit", - "hu": "Tetőparkoló", - "it": "Parcheggio sul tetto", - "ru": "Парковка на крыше", - "zh_Hant": "屋頂停車場", - "pt_BR": "Estacionamento no telhado" - } + "title": { + "en": "Bike parking", + "nl": "Fietsparking", + "fr": "Parking à vélo", + "gl": "Aparcadoiro de bicicletas", + "de": "Fahrrad-Parkplätze", + "hu": "Kerékpáros parkoló", + "it": "Parcheggio bici", + "zh_Hant": "單車停車場", + "ru": "Велопарковка", + "pl": "Parking dla rowerów", + "pt_BR": "Estacionamento de bicicletas" + }, + "tags": [ + "amenity=bicycle_parking" + ] } - ] - }, - { - "#": "Is covered?", - "question": { - "en": "Is this parking covered? Also select \"covered\" for indoor parkings.", - "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.", - "gl": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.", - "de": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.", - "fr": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur.", - "hu": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)", - "it": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno.", - "zh_Hant": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。", - "pt_BR": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." - }, - "condition": { - "and": [ - "bicycle_parking!=shed", - "location!=underground" - ] - }, - "mappings": [ - { - "if": "covered=yes", - "then": { - "en": "This parking is covered (it has a roof)", - "nl": "Deze parking is overdekt (er is een afdak)", - "gl": "Este aparcadoiro está cuberto (ten un teito)", - "de": "Dieser Parkplatz ist überdacht (er hat ein Dach)", - "fr": "Ce parking est couvert (il a un toit)", - "hu": "A parkoló fedett", - "it": "È un parcheggio coperto (ha un tetto)", - "zh_Hant": "這個停車場有遮蔽 (有屋頂)", - "ru": "Это крытая парковка (есть крыша/навес)", - "pt_BR": "Este estacionamento é coberto (tem um telhado)" - } - }, - { - "if": "covered=no", - "then": { - "en": "This parking is not covered", - "nl": "Deze parking is niet overdekt", - "gl": "Este aparcadoiro non está cuberto", - "de": "Dieser Parkplatz ist nicht überdacht", - "fr": "Ce parking n'est pas couvert", - "hu": "A parkoló nem fedett", - "it": "Non è un parcheggio coperto", - "zh_Hant": "這個停車場沒有遮蔽", - "ru": "Это открытая парковка", - "pt_BR": "Este estacionamento não é coberto" - } + ], + "title": { + "render": { + "en": "Bike parking", + "nl": "Fietsparking", + "fr": "Parking à vélo", + "gl": "Aparcadoiro de bicicletas", + "de": "Fahrrad-Parkplätze", + "hu": "Kerékpáros parkoló", + "it": "Parcheggio bici", + "zh_Hant": "單車停車場", + "ru": "Велопарковка", + "pl": "Parking dla rowerów", + "pt_BR": "Estacionamento de bicicletas" } - ] }, - { - "#": "Capacity", - "question": { - "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", - "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", - "nl": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", - "gl": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", - "de": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", - "it": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", - "zh_Hant": "這個單車停車場能放幾台單車 (包括裝箱單車)?" - }, - "render": { - "en": "Place for {capacity} bikes", - "fr": "Place pour {capacity} vélos", - "nl": "Plaats voor {capacity} fietsen", - "gl": "Lugar para {capacity} bicicletas", - "de": "Platz für {capacity} Fahrräder", - "it": "Posti per {capacity} bici", - "zh_Hant": "{capacity} 單車的地方", - "ru": "Место для {capacity} велосипеда(ов)", - "pt_BR": "Lugar para {capacity} bicicletas" - }, - "freeform": { - "key": "capacity", - "type": "nat" - } - }, - { - "#": "Access", - "question": { - "en": "Who can use this bicycle parking?", - "nl": "Wie mag er deze fietsenstalling gebruiken?", - "fr": "Qui peut utiliser ce parking à vélo ?", - "it": "Chi può usare questo parcheggio bici?", - "de": "Wer kann diesen Fahrradparplatz nutzen?", - "zh_Hant": "誰可以使用這個單車停車場?", - "ru": "Кто может пользоваться этой велопарковкой?", - "pt_BR": "Quem pode usar este estacionamento de bicicletas?" - }, - "render": { - "en": "{access}", - "de": "{access}", - "fr": "{access}", - "nl": "{access}", - "it": "{access}", - "ru": "{access}", - "id": "{access}", - "zh_Hant": "{access}", - "fi": "{access}", - "pt_BR": "{access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform used on 'access'-tag: possibly a wrong value" - ] - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "access=yes", - "then": { - "en": "Publicly accessible", - "nl": "Publiek toegankelijke fietsenstalling", - "fr": "Accessible publiquement", - "it": "Accessibile pubblicamente", - "de": "Öffentlich zugänglich", - "zh_Hant": "公開可用", - "pt_BR": "Acessível ao público" - } + "question": { + "en": "What is the type of this bicycle parking?", + "nl": "Van welk type is deze fietsparking?", + "fr": "Quel type de parking à vélos est-ce ?", + "gl": "Que tipo de aparcadoiro de bicicletas é?", + "de": "Was ist die Art dieses Fahrrad-Parkplatzes?", + "hu": "Milyen típusú ez a kerékpáros parkoló?", + "it": "Di che tipo di parcheggio bici si tratta?", + "ru": "К какому типу относится эта велопарковка?", + "zh_Hant": "這是那種類型的單車停車場?", + "pl": "Jaki jest typ tego parkingu dla rowerów?", + "pt_BR": "Qual o tipo deste estacionamento de bicicletas?" + }, + "render": { + "en": "This is a bicycle parking of the type: {bicycle_parking}", + "nl": "Dit is een fietsparking van het type: {bicycle_parking}", + "fr": "Ceci est un parking à vélo de type {bicycle_parking}", + "gl": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}", + "de": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}", + "hu": "Ez egy {bicycle_parking} típusú kerékpáros parkoló", + "it": "È un parcheggio bici del tipo: {bicycle_parking}", + "zh_Hant": "這個單車停車場的類型是:{bicycle_parking}", + "ru": "Это велопарковка типа {bicycle_parking}", + "pl": "Jest to parking rowerowy typu: {bicycle_parking}", + "pt_BR": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" + }, + "freeform": { + "key": "bicycle_parking", + "addExtraTags": [ + "fixme=Freeform used on 'bicycle_parking'-tag: possibly a wrong value" + ] + }, + "mappings": [ + { + "if": "bicycle_parking=stands", + "then": { + "en": "Staple racks ", + "nl": "Nietjes ", + "fr": "Arceaux ", + "gl": "De roda (Stands) ", + "de": "Fahrradbügel ", + "hu": "\"U\" ", + "it": "Archetti ", + "zh_Hant": "單車架 " + } + }, + { + "if": "bicycle_parking=wall_loops", + "then": { + "en": "Wheel rack/loops ", + "nl": "Wielrek/lussen ", + "fr": "Pinces-roues ", + "gl": "Aros ", + "de": "Metallgestänge ", + "hu": "Kengyeles ", + "it": "Scolapiatti ", + "zh_Hant": "車輪架/圓圈 " + } + }, + { + "if": "bicycle_parking=handlebar_holder", + "then": { + "en": "Handlebar holder ", + "nl": "Stuurhouder ", + "fr": "Support guidon ", + "gl": "Cadeado para guiador ", + "de": "Halter für Fahrradlenker ", + "it": "Blocca manubrio ", + "zh_Hant": "車把架 " + } + }, + { + "if": "bicycle_parking=rack", + "then": { + "en": "Rack ", + "nl": "Rek ", + "fr": "Râtelier ", + "gl": "Cremalleira ", + "de": "Gestell ", + "zh_Hant": "車架", + "it": "Rastrelliera ", + "ru": "Стойка " + } + }, + { + "if": "bicycle_parking=two_tier", + "then": { + "en": "Two-tiered ", + "nl": "Dubbel (twee verdiepingen) ", + "fr": "Superposé ", + "gl": "Dobre cremalleira ", + "de": "Zweistufig ", + "hu": "Kétszintű ", + "zh_Hant": "兩層", + "it": "A due piani ", + "ru": "Двухуровневая " + } + }, + { + "if": "bicycle_parking=shed", + "then": { + "en": "Shed ", + "nl": "Schuur ", + "fr": "Abri ", + "gl": "Abeiro ", + "de": "Schuppen ", + "hu": "Fészer ", + "zh_Hant": "車棚 ", + "it": "Rimessa ", + "ru": "Навес " + } + }, + { + "if": "bicycle_parking=bollard", + "then": { + "en": "Bollard ", + "nl": "Paal met ring ", + "fr": "Potelet ", + "it": "Colonnina ", + "de": "Poller ", + "zh_Hant": "柱子 " + } + }, + { + "if": "bicycle_parking=floor", + "then": { + "en": "An area on the floor which is marked for bicycle parking", + "nl": "Een oppervlakte die gemarkeerd is om fietsen te parkeren", + "fr": "Zone au sol qui est marquée pour le stationnement des vélos", + "it": "Una zona del pavimento che è marcata per il parcheggio delle bici", + "de": "Ein Bereich auf dem Boden, der für das Abstellen von Fahrrädern gekennzeichnet ist", + "zh_Hant": "樓層當中標示為單車停車場的區域" + } + } + ], + "id": "Bicycle parking type" }, { - "if": "access=customers", - "then": { - "en": "Access is primarily for visitors to a business", - "nl": "Klanten van de zaak of winkel", - "fr": "Accès destiné principalement aux visiteurs d'un lieu", - "it": "Accesso destinato principalmente ai visitatori di un’attività", - "zh_Hant": "通行性主要是為了企業的顧客", - "pt_BR": "Acesso é principalmente para visitantes de uma empresa" - } + "question": { + "en": "What is the relative location of this bicycle parking?", + "nl": "Wat is de relatieve locatie van deze parking??", + "fr": "Quelle est la position relative de ce parking à vélo ?", + "it": "Qual è la posizione relativa di questo parcheggio bici?", + "zh_Hant": "這個單車停車場的相對位置是?", + "pl": "Jaka jest względna lokalizacja tego parkingu rowerowego?", + "pt_BR": "Qual a localização relativa deste estacionamento de bicicletas?" + }, + "mappings": [ + { + "if": "location=underground", + "then": { + "en": "Underground parking", + "nl": "Ondergrondse parking", + "fr": "Parking souterrain", + "it": "Parcheggio sotterraneo", + "ru": "Подземная парковка", + "de": "Tiefgarage", + "zh_Hant": "地下停車場", + "pt_BR": "Estacionamento subterrâneo" + } + }, + { + "if": "location=underground", + "then": { + "en": "Underground parking", + "nl": "Ondergrondse parking", + "fr": "Parking souterrain", + "it": "Parcheggio sotterraneo", + "ru": "Подземная парковка", + "de": "Tiefgarage", + "zh_Hant": "地下停車場", + "pt_BR": "Estacionamento subterrâneo" + } + }, + { + "if": "location=surface", + "then": { + "en": "Surface level parking", + "nl": "Parking op de begane grond", + "fr": "Parking en surface", + "hu": "Felszíni parkoló", + "it": "Parcheggio in superficie", + "de": "Ebenerdiges Parken", + "zh_Hant": "地面停車場", + "pt_BR": "Estacionamento de superfície" + } + }, + { + "if": "location=", + "then": { + "en": "Surface level parking", + "nl": "Parking op de begane grond", + "fr": "Parking en surface", + "hu": "Felszíni parkoló", + "it": "Parcheggio in superficie", + "de": "Ebenerdiges Parken", + "zh_Hant": "地面層停車場", + "pt_BR": "Estacionamento ao nível da superfície" + }, + "hideInAnwser": true + }, + { + "if": "location=rooftop", + "then": { + "en": "Rooftop parking", + "nl": "Dakparking", + "fr": "Parking sur un toit", + "hu": "Tetőparkoló", + "it": "Parcheggio sul tetto", + "ru": "Парковка на крыше", + "zh_Hant": "屋頂停車場", + "pt_BR": "Estacionamento no telhado" + } + } + ], + "id": "Underground?" }, { - "if": "access=private", - "then": { - "en": "Access is limited to members of a school, company or organisation", - "nl": "Private fietsenstalling van een school, een bedrijf, ...", - "fr": "Accès limité aux membres d'une école, entreprise ou organisation", - "it": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione", - "zh_Hant": "通行性僅限學校、公司或組織的成員", - "pt_BR": "Acesso é limitado aos membros de uma escola, companhia ou organização" - } + "question": { + "en": "Is this parking covered? Also select \"covered\" for indoor parkings.", + "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.", + "gl": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.", + "de": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.", + "fr": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur.", + "hu": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)", + "it": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno.", + "zh_Hant": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。", + "pt_BR": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." + }, + "condition": { + "and": [ + "bicycle_parking!=shed", + "location!=underground" + ] + }, + "mappings": [ + { + "if": "covered=yes", + "then": { + "en": "This parking is covered (it has a roof)", + "nl": "Deze parking is overdekt (er is een afdak)", + "gl": "Este aparcadoiro está cuberto (ten un teito)", + "de": "Dieser Parkplatz ist überdacht (er hat ein Dach)", + "fr": "Ce parking est couvert (il a un toit)", + "hu": "A parkoló fedett", + "it": "È un parcheggio coperto (ha un tetto)", + "zh_Hant": "這個停車場有遮蔽 (有屋頂)", + "ru": "Это крытая парковка (есть крыша/навес)", + "pt_BR": "Este estacionamento é coberto (tem um telhado)" + } + }, + { + "if": "covered=no", + "then": { + "en": "This parking is not covered", + "nl": "Deze parking is niet overdekt", + "gl": "Este aparcadoiro non está cuberto", + "de": "Dieser Parkplatz ist nicht überdacht", + "fr": "Ce parking n'est pas couvert", + "hu": "A parkoló nem fedett", + "it": "Non è un parcheggio coperto", + "zh_Hant": "這個停車場沒有遮蔽", + "ru": "Это открытая парковка", + "pt_BR": "Este estacionamento não é coberto" + } + } + ], + "id": "Is covered?" + }, + { + "question": { + "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", + "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", + "nl": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", + "gl": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", + "de": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", + "it": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", + "zh_Hant": "這個單車停車場能放幾台單車 (包括裝箱單車)?" + }, + "render": { + "en": "Place for {capacity} bikes", + "fr": "Place pour {capacity} vélos", + "nl": "Plaats voor {capacity} fietsen", + "gl": "Lugar para {capacity} bicicletas", + "de": "Platz für {capacity} Fahrräder", + "it": "Posti per {capacity} bici", + "zh_Hant": "{capacity} 單車的地方", + "ru": "Место для {capacity} велосипеда(ов)", + "pt_BR": "Lugar para {capacity} bicicletas" + }, + "freeform": { + "key": "capacity", + "type": "nat" + }, + "id": "Capacity" + }, + { + "question": { + "en": "Who can use this bicycle parking?", + "nl": "Wie mag er deze fietsenstalling gebruiken?", + "fr": "Qui peut utiliser ce parking à vélo ?", + "it": "Chi può usare questo parcheggio bici?", + "de": "Wer kann diesen Fahrradparplatz nutzen?", + "zh_Hant": "誰可以使用這個單車停車場?", + "ru": "Кто может пользоваться этой велопарковкой?", + "pt_BR": "Quem pode usar este estacionamento de bicicletas?" + }, + "render": { + "en": "{access}", + "de": "{access}", + "fr": "{access}", + "nl": "{access}", + "it": "{access}", + "ru": "{access}", + "id": "{access}", + "zh_Hant": "{access}", + "fi": "{access}", + "pt_BR": "{access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform used on 'access'-tag: possibly a wrong value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Publicly accessible", + "nl": "Publiek toegankelijke fietsenstalling", + "fr": "Accessible publiquement", + "it": "Accessibile pubblicamente", + "de": "Öffentlich zugänglich", + "zh_Hant": "公開可用", + "pt_BR": "Acessível ao público" + } + }, + { + "if": "access=customers", + "then": { + "en": "Access is primarily for visitors to a business", + "nl": "Klanten van de zaak of winkel", + "fr": "Accès destiné principalement aux visiteurs d'un lieu", + "it": "Accesso destinato principalmente ai visitatori di un’attività", + "zh_Hant": "通行性主要是為了企業的顧客", + "pt_BR": "Acesso é principalmente para visitantes de uma empresa" + } + }, + { + "if": "access=private", + "then": { + "en": "Access is limited to members of a school, company or organisation", + "nl": "Private fietsenstalling van een school, een bedrijf, ...", + "fr": "Accès limité aux membres d'une école, entreprise ou organisation", + "it": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione", + "zh_Hant": "通行性僅限學校、公司或組織的成員", + "pt_BR": "Acesso é limitado aos membros de uma escola, companhia ou organização" + } + } + ], + "id": "Access" + }, + { + "question": { + "en": "Does this bicycle parking have spots for cargo bikes?", + "nl": "Heeft deze fietsparking plaats voor bakfietsen?", + "gl": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?", + "de": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?", + "fr": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?", + "it": "Questo parcheggio dispone di posti specifici per le bici da trasporto?", + "zh_Hant": "這個單車停車場有地方放裝箱的單車嗎?", + "pt_BR": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" + }, + "mappings": [ + { + "if": "cargo_bike=yes", + "then": { + "en": "This parking has room for cargo bikes", + "nl": "Deze parking heeft plaats voor bakfietsen", + "gl": "Este aparcadoiro ten espazo para bicicletas de carga.", + "de": "Dieser Parkplatz bietet Platz für Lastenfahrräder", + "fr": "Ce parking a de la place pour les vélos cargo", + "it": "Questo parcheggio ha posto per bici da trasporto", + "zh_Hant": "這個停車場有地方可以放裝箱單車", + "pt_BR": "Este estacionamento tem vagas para bicicletas de carga" + } + }, + { + "if": "cargo_bike=designated", + "then": { + "en": "This parking has designated (official) spots for cargo bikes.", + "nl": "Er zijn speciale plaatsen voorzien voor bakfietsen", + "gl": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga.", + "de": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder.", + "fr": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo.", + "it": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto.", + "zh_Hant": "這停車場有設計 (官方) 空間給裝箱的單車。", + "pt_BR": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." + } + }, + { + "if": "cargo_bike=no", + "then": { + "en": "You're not allowed to park cargo bikes", + "nl": "Je mag hier geen bakfietsen parkeren", + "gl": "Non está permitido aparcar bicicletas de carga", + "de": "Es ist nicht erlaubt, Lastenfahrräder zu parken", + "fr": "Il est interdit de garer des vélos cargo", + "it": "Il parcheggio delle bici da trasporto è proibito", + "pt_BR": "Você não tem permissão para estacionar bicicletas de carga" + } + } + ], + "id": "Cargo bike spaces?" + }, + { + "question": { + "en": "How many cargo bicycles fit in this bicycle parking?", + "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", + "fr": "Combien de vélos de transport entrent dans ce parking à vélos ?", + "gl": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", + "de": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", + "it": "Quante bici da trasporto entrano in questo parcheggio per bici?", + "pt_BR": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?" + }, + "render": { + "en": "This parking fits {capacity:cargo_bike} cargo bikes", + "nl": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen", + "fr": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport", + "gl": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga", + "de": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder", + "it": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto", + "pt_BR": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" + }, + "condition": "cargo_bike~designated|yes", + "freeform": { + "key": "capacity:cargo_bike", + "type": "nat" + }, + "id": "Cargo bike capacity?" } - ] - }, - { - "#": "Cargo bike spaces?", - "question": { - "en": "Does this bicycle parking have spots for cargo bikes?", - "nl": "Heeft deze fietsparking plaats voor bakfietsen?", - "gl": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?", - "de": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?", - "fr": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?", - "it": "Questo parcheggio dispone di posti specifici per le bici da trasporto?", - "zh_Hant": "這個單車停車場有地方放裝箱的單車嗎?", - "pt_BR": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" - }, - "mappings": [ - { - "if": "cargo_bike=yes", - "then": { - "en": "This parking has room for cargo bikes", - "nl": "Deze parking heeft plaats voor bakfietsen", - "gl": "Este aparcadoiro ten espazo para bicicletas de carga.", - "de": "Dieser Parkplatz bietet Platz für Lastenfahrräder", - "fr": "Ce parking a de la place pour les vélos cargo", - "it": "Questo parcheggio ha posto per bici da trasporto", - "zh_Hant": "這個停車場有地方可以放裝箱單車", - "pt_BR": "Este estacionamento tem vagas para bicicletas de carga" - } - }, - { - "if": "cargo_bike=designated", - "then": { - "en": "This parking has designated (official) spots for cargo bikes.", - "nl": "Er zijn speciale plaatsen voorzien voor bakfietsen", - "gl": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga.", - "de": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder.", - "fr": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo.", - "it": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto.", - "zh_Hant": "這停車場有設計 (官方) 空間給裝箱的單車。", - "pt_BR": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." - } - }, - { - "if": "cargo_bike=no", - "then": { - "en": "You're not allowed to park cargo bikes", - "nl": "Je mag hier geen bakfietsen parkeren", - "gl": "Non está permitido aparcar bicicletas de carga", - "de": "Es ist nicht erlaubt, Lastenfahrräder zu parken", - "fr": "Il est interdit de garer des vélos cargo", - "it": "Il parcheggio delle bici da trasporto è proibito", - "pt_BR": "Você não tem permissão para estacionar bicicletas de carga" - } - } - ] - }, - { - "#": "Cargo bike capacity?", - "question": { - "en": "How many cargo bicycles fit in this bicycle parking?", - "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", - "fr": "Combien de vélos de transport entrent dans ce parking à vélos ?", - "gl": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", - "de": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", - "it": "Quante bici da trasporto entrano in questo parcheggio per bici?", - "pt_BR": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?" - }, - "render": { - "en": "This parking fits {capacity:cargo_bike} cargo bikes", - "nl": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen", - "fr": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport", - "gl": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga", - "de": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder", - "it": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto", - "pt_BR": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" - }, - "condition": "cargo_bike~designated|yes", - "freeform": { - "key": "capacity:cargo_bike", - "type": "nat" - } - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index df372236f..cd202c6c8 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -1,725 +1,735 @@ { - "id": "bike_repair_station", - "name": { - "en": "Bike stations (repair, pump or both)", - "nl": "Fietspunten (herstel, pomp of allebei)", - "fr": "Station velo (réparation, pompe à vélo)", - "gl": "Estación de bicicletas (arranxo, bomba de ar ou ambos)", - "de": "Fahrradstationen (Reparatur, Pumpe oder beides)", - "it": "Stazioni bici (riparazione, gonfiaggio o entrambi)", - "pt_BR": "Estações de bicicletas (reparo, bomba ou ambos)" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "amenity=bicycle_repair_station" - ] - } - }, - "title": { - "render": { - "en": "Bike station (pump & repair)", - "nl": "Herstelpunt met pomp", - "fr": "Point station velo avec pompe", - "gl": "Estación de bicicletas (arranxo e bomba de ar)", - "de": "Fahrradstation (Pumpe & Reparatur)", - "it": "Stazione bici (gonfiaggio & riparazione)", - "pt_BR": "Estação de bicicletas (bomba e reparo)" + "id": "bike_repair_station", + "name": { + "en": "Bike stations (repair, pump or both)", + "nl": "Fietspunten (herstel, pomp of allebei)", + "fr": "Station velo (réparation, pompe à vélo)", + "gl": "Estación de bicicletas (arranxo, bomba de ar ou ambos)", + "de": "Fahrradstationen (Reparatur, Pumpe oder beides)", + "it": "Stazioni bici (riparazione, gonfiaggio o entrambi)", + "pt_BR": "Estações de bicicletas (reparo, bomba ou ambos)" }, - "mappings": [ - { - "if": { - "or": [ - "service:bicycle:pump=no", - "service:bicycle:pump:operational_status=broken" - ] - }, - "then": { - "en": "Bike repair station", - "nl": "Herstelpunt", - "fr": "Point de réparation velo", - "gl": "Estación de arranxo de bicicletas", - "de": "Fahrrad-Reparaturstation", - "it": "Stazione riparazione bici", - "pt_BR": "Estação de reparo de bicicletas" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_repair_station" + ] } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=yes" - ] + }, + "title": { + "render": { + "en": "Bike station (pump & repair)", + "nl": "Herstelpunt met pomp", + "fr": "Point station velo avec pompe", + "gl": "Estación de bicicletas (arranxo e bomba de ar)", + "de": "Fahrradstation (Pumpe & Reparatur)", + "it": "Stazione bici (gonfiaggio & riparazione)", + "pt_BR": "Estação de bicicletas (bomba e reparo)" }, - "then": { - "en": "Bike repair station", - "nl": "Herstelpunt", - "fr": "Point de réparation", - "gl": "Estación de arranxo de bicicletas", - "de": "Fahrrad-Reparaturstation", - "it": "Stazione riparazione bici", - "pt_BR": "Estação de reparo de bicicletas" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump:operational_status=broken", + "mappings": [ { - "or": [ - "service:bicycle:tools=no", - "service:bicycle:tools=" - ] + "if": { + "or": [ + "service:bicycle:pump=no", + "service:bicycle:pump:operational_status=broken" + ] + }, + "then": { + "en": "Bike repair station", + "nl": "Herstelpunt", + "fr": "Point de réparation velo", + "gl": "Estación de arranxo de bicicletas", + "de": "Fahrrad-Reparaturstation", + "it": "Stazione riparazione bici", + "pt_BR": "Estação de reparo de bicicletas" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=yes" + ] + }, + "then": { + "en": "Bike repair station", + "nl": "Herstelpunt", + "fr": "Point de réparation", + "gl": "Estación de arranxo de bicicletas", + "de": "Fahrrad-Reparaturstation", + "it": "Stazione riparazione bici", + "pt_BR": "Estação de reparo de bicicletas" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump:operational_status=broken", + { + "or": [ + "service:bicycle:tools=no", + "service:bicycle:tools=" + ] + } + ] + }, + "then": { + "en": "Broken pump", + "nl": "Kapotte fietspomp", + "fr": "Pompe cassée", + "gl": "Bomba de ar estragada", + "de": "Kaputte Pumpe", + "it": "Pompa rotta", + "ru": "Сломанный насос", + "pt_BR": "Bomba quebrada" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=no", + "name~*" + ] + }, + "then": { + "en": "Bicycle pump {name}", + "nl": "Fietspomp {name}", + "fr": "Pompe de vélo {name}", + "gl": "Bomba de ar {name}", + "de": "Fahrradpumpe {name}", + "it": "Pompa per bici {name}", + "ru": "Велосипедный насос {name}", + "pt_BR": "Bomba de bicicleta {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=no" + ] + }, + "then": { + "en": "Bicycle pump", + "nl": "Fietspomp", + "fr": "Pompe de vélo", + "gl": "Bomba de ar", + "de": "Fahrradpumpe", + "it": "Pompa per bici", + "ru": "Велосипедный насос", + "pt_BR": "Bomba de bicicleta" + } } - ] - }, - "then": { - "en": "Broken pump", - "nl": "Kapotte fietspomp", - "fr": "Pompe cassée", - "gl": "Bomba de ar estragada", - "de": "Kaputte Pumpe", - "it": "Pompa rotta", - "ru": "Сломанный насос", - "pt_BR": "Bomba quebrada" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=no", - "name~*" - ] - }, - "then": { - "en": "Bicycle pump {name}", - "nl": "Fietspomp {name}", - "fr": "Pompe de vélo {name}", - "gl": "Bomba de ar {name}", - "de": "Fahrradpumpe {name}", - "it": "Pompa per bici {name}", - "ru": "Велосипедный насос {name}", - "pt_BR": "Bomba de bicicleta {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=no" - ] - }, - "then": { - "en": "Bicycle pump", - "nl": "Fietspomp", - "fr": "Pompe de vélo", - "gl": "Bomba de ar", - "de": "Fahrradpumpe", - "it": "Pompa per bici", - "ru": "Велосипедный насос", - "pt_BR": "Bomba de bicicleta" - } - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent", - "roaming": true - }, - "defaults" - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Which services are available at this bike station?", - "nl": "Welke functies biedt dit fietspunt?", - "fr": "Quels services sont valables à cette station vélo ?", - "gl": "Que servizos están dispoñíbeis nesta estación de bicicletas?", - "de": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?", - "it": "Quali servizi sono disponibili in questa stazione per bici?", - "pt_BR": "Quais serviços estão disponíveis nesta estação de bicicletas?" - }, - "mappings": [ - { - "if": { - "and": [ - "service:bicycle:tools=no", - "service:bicycle:pump=yes" - ] - }, - "then": { - "en": "There is only a pump present", - "nl": "Er is enkel een pomp aanwezig", - "fr": "Il y a seulement une pompe", - "gl": "Só hai unha bomba de ar presente", - "de": "Es ist nur eine Pumpe vorhanden", - "it": "C’è solamente una pompa presente", - "pt_BR": "Há somente uma bomba presente" - } - }, - { - "if": { - "and": [ - "service:bicycle:tools=yes", - "service:bicycle:pump=no" - ] - }, - "then": { - "en": "There are only tools (screwdrivers, pliers...) present", - "nl": "Er is enkel gereedschap aanwezig (schroevendraaier, tang...)", - "fr": "Il y a seulement des outils (tournevis, pinces...)", - "gl": "Só hai ferramentas (desaparafusadores, alicates...) presentes", - "de": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden", - "it": "Ci sono solo degli attrezzi (cacciaviti, pinze…) presenti", - "pt_BR": "Há somente ferramentas (chaves de fenda, alicates...) presentes" - } - }, - { - "if": { - "and": [ - "service:bicycle:tools=yes", - "service:bicycle:pump=yes" - ] - }, - "then": { - "en": "There are both tools and a pump present", - "nl": "Er is zowel een pomp als gereedschap aanwezig", - "fr": "Il y a des outils et une pompe", - "gl": "Hai ferramentas e unha bomba de ar presentes", - "de": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden", - "it": "Ci sono sia attrezzi che pompa presenti", - "pt_BR": "Há tanto ferramentas e uma bomba presente" - } - } - ] - }, - { - "question": { - "en": "Who maintains this cycle pump?", - "nl": "Wie beheert deze fietspomp?", - "fr": "Qui maintient cette pompe à vélo ?", - "it": "Chi gestisce questa pompa per bici?", - "de": "Wer wartet diese Fahrradpumpe?", - "pt_BR": "Quem faz a manutenção desta bomba de ciclo?" - }, - "render": { - "nl": "Beheer door {operator}", - "en": "Maintained by {operator}", - "fr": "Mantenue par {operator}", - "it": "Manutenuta da {operator}", - "de": "Gewartet von {operator}", - "pt_BR": "Mantida por {operator}" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "De Fietsambassade Gent", - "hideInAnswer": "_country!=be" - } - ] - }, - { - "question": { - "en": "What is the email address of the maintainer?", - "nl": "Wat is het email-adres van de beheerder?" - }, - "freeform": { - "key": "email", - "type": "email" - }, - "render": "{email}" - }, - { - "question": { - "en": "What is the phone number of the maintainer?", - "nl": "Wat is het telefoonnummer van de beheerder?" - }, - "freeform": { - "key": "phone", - "type": "phone" - }, - "render": "{phone}" - }, - { - "question": { - "nl": "Wanneer is dit fietsherstelpunt open?", - "en": "When is this bicycle repair point open?", - "fr": "Quand ce point de réparation de vélo est-il ouvert ?", - "it": "Quando è aperto questo punto riparazione bici?", - "de": "Wann ist diese Fahrradreparaturstelle geöffnet?", - "ru": "Когда работает эта точка обслуживания велосипедов?" - }, - "render": "{opening_hours_table()}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "nl": "Dag en nacht open", - "en": "Always open", - "fr": "Ouvert en permanence", - "it": "Sempre aperto", - "de": "Immer geöffnet", - "ru": "Всегда открыто", - "pt_BR": "Sempre aberto" - } - }, - { - "if": "opening_hours=", - "then": { - "nl": "Dag en nacht open", - "en": "Always open", - "fr": "Ouvert en permanence", - "it": "Sempre aperto", - "de": "Immer geöffnet", - "pt_BR": "Sempre aberto" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Does this bike repair station have a special tool to repair your bike chain?", - "nl": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?", - "fr": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?", - "gl": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?", - "de": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?", - "it": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" - }, - "condition": "service:bicycle:tools=yes", - "mappings": [ - { - "if": "service:bicycle:chain_tool=yes", - "then": { - "en": "There is a chain tool", - "nl": "Er is een reparatieset voor je ketting", - "fr": "Il y a un outil pour réparer la chaine", - "gl": "Hai unha ferramenta para a cadea", - "de": "Es gibt ein Kettenwerkzeug", - "it": "È presente un utensile per riparare la catena", - "pt_BR": "Há uma ferramenta de corrente" - } - }, - { - "if": "service:bicycle:chain_tool=no", - "then": { - "en": "There is no chain tool", - "nl": "Er is geen reparatieset voor je ketting", - "fr": "Il n'y a pas d'outil pour réparer la chaine", - "gl": "Non hai unha ferramenta para a cadea", - "de": "Es gibt kein Kettenwerkzeug", - "it": "Non è presente un utensile per riparare la catena", - "pt_BR": "Não há uma ferramenta de corrente" - } - } - ] - }, - { - "question": { - "en": "Does this bike station have a hook to hang your bike on or a stand to raise it?", - "nl": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?", - "fr": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?", - "gl": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?", - "de": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?", - "it": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" - }, - "condition": "service:bicycle:tools=yes", - "mappings": [ - { - "if": "service:bicycle:stand=yes", - "then": { - "en": "There is a hook or stand", - "nl": "Er is een haak of standaard", - "fr": "Il y a un crochet ou une accroche", - "gl": "Hai un guindastre ou soporte", - "de": "Es gibt einen Haken oder Ständer", - "it": "C’è un gancio o un supporto", - "pt_BR": "Há um gancho ou um suporte" - } - }, - { - "if": "service:bicycle:stand=no", - "then": { - "en": "There is no hook or stand", - "nl": "Er is geen haak of standaard", - "fr": "Il n'y pas de crochet ou d'accroche", - "gl": "Non hai un guindastre ou soporte", - "de": "Es gibt keinen Haken oder Ständer", - "it": "Non c’è né un gancio né un supporto", - "pt_BR": "Não há um gancho ou um suporte" - } - } - ] - }, - { - "#": "Operational status", - "question": { - "en": "Is the bike pump still operational?", - "nl": "Werkt de fietspomp nog?", - "fr": "La pompe à vélo fonctionne-t-elle toujours ?", - "gl": "Segue a funcionar a bomba de ar?", - "de": "Ist die Fahrradpumpe noch funktionstüchtig?", - "it": "La pompa per bici è sempre funzionante?", - "ru": "Велосипедный насос все еще работает?", - "pl": "Czy pompka rowerowa jest nadal sprawna?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "service:bicycle:pump:operational_status=broken", - "then": { - "en": "The bike pump is broken", - "nl": "De fietspomp is kapot", - "fr": "La pompe à vélo est cassée", - "gl": "A bomba de ar está estragada", - "de": "Die Fahrradpumpe ist kaputt", - "it": "La pompa per bici è guasta", - "ru": "Велосипедный насос сломан", - "pl": "Pompka rowerowa jest zepsuta" - } - }, - { - "if": "service:bicycle:pump:operational_status=", - "then": { - "en": "The bike pump is operational", - "nl": "De fietspomp werkt nog", - "fr": "La pompe est opérationnelle", - "gl": "A bomba de ar está operativa", - "de": "Die Fahrradpumpe ist betriebsbereit", - "it": "La pompa per bici funziona", - "ru": "Велосипедный насос работает", - "pl": "Pompka rowerowa jest sprawna" - } - } - ] - }, - { - "#": "Email maintainer", - "condition": { - "and": [ - "email~*", - "service:bicycle:pump:operational_status=broken" ] - }, - "render": { - "en": "Report this bicycle pump as broken", - "nl": "Rapporteer deze fietspomp als kapot" - } }, - { - "question": { - "en": "What valves are supported?", - "nl": "Welke ventielen werken er met de pomp?", - "fr": "Quelles valves sont compatibles ?", - "gl": "Que válvulas son compatíbeis?", - "de": "Welche Ventile werden unterstützt?", - "it": "Quali valvole sono supportate?", - "pl": "Jakie zawory są obsługiwane?" - }, - "render": { - "en": "This pump supports the following valves: {valves}", - "nl": "Deze pomp werkt met de volgende ventielen: {valves}", - "fr": "Cette pompe est compatible avec les valves suivantes : {valves}", - "gl": "Esta bomba de ar admite as seguintes válvulas: {valves}", - "de": "Diese Pumpe unterstützt die folgenden Ventile: {valves}", - "it": "Questa pompa è compatibile con le seguenti valvole: {valves}", - "ru": "Этот насос поддерживает следующие клапаны: {valves}", - "pl": "Ta pompka obsługuje następujące zawory: {valves}" - }, - "freeform": { - "#addExtraTags": [ - "fixme=Freeform 'valves'-tag used: possibly a wrong value" - ], - "key": "valves" - }, - "multiAnswer": true, - "mappings": [ + "titleIcons": [ { - "if": "valves=sclaverand", - "then": { - "en": "Sclaverand (also known as Presta)", - "nl": "Sclaverand (ook gekend als Presta)", - "fr": "Sclaverand (aussi appelé Presta)", - "gl": "Sclaverand (tamén coñecido como Presta)", - "de": "Sklaverand (auch bekannt als Presta)", - "it": "Sclaverand (detta anche Presta)", - "ru": "Клапан Presta (также известный как французский клапан)" - } + "render": "", + "condition": "operator=De Fietsambassade Gent", + "roaming": true + }, + "defaults" + ], + "tagRenderings": [ + "images", + { + "id": "bike_repair_station-available-services", + "question": { + "en": "Which services are available at this bike station?", + "nl": "Welke functies biedt dit fietspunt?", + "fr": "Quels services sont valables à cette station vélo ?", + "gl": "Que servizos están dispoñíbeis nesta estación de bicicletas?", + "de": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?", + "it": "Quali servizi sono disponibili in questa stazione per bici?", + "pt_BR": "Quais serviços estão disponíveis nesta estação de bicicletas?" + }, + "mappings": [ + { + "if": { + "and": [ + "service:bicycle:tools=no", + "service:bicycle:pump=yes" + ] + }, + "then": { + "en": "There is only a pump present", + "nl": "Er is enkel een pomp aanwezig", + "fr": "Il y a seulement une pompe", + "gl": "Só hai unha bomba de ar presente", + "de": "Es ist nur eine Pumpe vorhanden", + "it": "C’è solamente una pompa presente", + "pt_BR": "Há somente uma bomba presente" + } + }, + { + "if": { + "and": [ + "service:bicycle:tools=yes", + "service:bicycle:pump=no" + ] + }, + "then": { + "en": "There are only tools (screwdrivers, pliers...) present", + "nl": "Er is enkel gereedschap aanwezig (schroevendraaier, tang...)", + "fr": "Il y a seulement des outils (tournevis, pinces...)", + "gl": "Só hai ferramentas (desaparafusadores, alicates...) presentes", + "de": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden", + "it": "Ci sono solo degli attrezzi (cacciaviti, pinze…) presenti", + "pt_BR": "Há somente ferramentas (chaves de fenda, alicates...) presentes" + } + }, + { + "if": { + "and": [ + "service:bicycle:tools=yes", + "service:bicycle:pump=yes" + ] + }, + "then": { + "en": "There are both tools and a pump present", + "nl": "Er is zowel een pomp als gereedschap aanwezig", + "fr": "Il y a des outils et une pompe", + "gl": "Hai ferramentas e unha bomba de ar presentes", + "de": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden", + "it": "Ci sono sia attrezzi che pompa presenti", + "pt_BR": "Há tanto ferramentas e uma bomba presente" + } + } + ] }, { - "if": "valves=dunlop", - "then": { - "en": "Dunlop", - "nl": "Dunlop", - "fr": "Dunlop", - "gl": "Dunlop", - "de": "Dunlop", - "it": "Dunlop", - "ru": "Клапан Dunlop" - } + "question": { + "en": "Who maintains this cycle pump?", + "nl": "Wie beheert deze fietspomp?", + "fr": "Qui maintient cette pompe à vélo ?", + "it": "Chi gestisce questa pompa per bici?", + "de": "Wer wartet diese Fahrradpumpe?", + "pt_BR": "Quem faz a manutenção desta bomba de ciclo?" + }, + "render": { + "nl": "Beheer door {operator}", + "en": "Maintained by {operator}", + "fr": "Mantenue par {operator}", + "it": "Manutenuta da {operator}", + "de": "Gewartet von {operator}", + "pt_BR": "Mantida por {operator}" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "De Fietsambassade Gent", + "hideInAnswer": "_country!=be" + } + ], + "id": "bike_repair_station-operator" }, { - "if": "valves=schrader", - "then": { - "en": "Schrader (cars)", - "nl": "Schrader (auto's)", - "fr": "Schrader (les valves de voitures)", - "gl": "Schrader (para automóbiles)", - "de": "Schrader (Autos)", - "it": "Schrader (valvola delle auto)" - } - } - ] - }, - { - "question": { - "en": "Is this an electric bike pump?", - "nl": "Is dit een electrische fietspomp?", - "fr": "Est-ce que cette pompe est électrique ?", - "gl": "Esta é unha bomba de ar eléctrica?", - "de": "Ist dies eine elektrische Fahrradpumpe?", - "it": "Questa pompa per bici è elettrica?", - "ru": "Это электрический велосипедный насос?", - "pl": "Czy jest to elektryczna pompka do roweru?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "manual=yes", - "then": { - "en": "Manual pump", - "nl": "Manuele pomp", - "fr": "Pompe manuelle", - "gl": "Bomba de ar manual", - "de": "Manuelle Pumpe", - "it": "Pompa manuale", - "ru": "Ручной насос", - "pl": "Pompa ręczna", - "pt_BR": "Bomba manual" - } + "question": { + "en": "What is the email address of the maintainer?", + "nl": "Wat is het email-adres van de beheerder?" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "render": "{email}", + "id": "bike_repair_station-email" }, { - "if": "manual=no", - "then": { - "en": "Electrical pump", - "nl": "Electrische pomp", - "fr": "Pompe électrique", - "gl": "Bomba de ar eléctrica", - "de": "Elektrische Pumpe", - "it": "Pompa elettrica", - "ru": "Электрический насос", - "pl": "Pompka elektryczna", - "pt_BR": "Bomba elétrica" - } - } - ] - }, - { - "question": { - "en": "Does the pump have a pressure indicator or manometer?", - "nl": "Heeft deze pomp een luchtdrukmeter?", - "fr": "Est-ce que la pompe à un manomètre integré ?", - "gl": "Ten a bomba de ar un indicador de presión ou un manómetro?", - "de": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?", - "it": "Questa pompa ha l’indicatore della pressione o il manometro?", - "pl": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "manometer=yes", - "then": { - "en": "There is a manometer", - "nl": "Er is een luchtdrukmeter", - "fr": "Il y a un manomètre", - "gl": "Hai manómetro", - "de": "Es gibt ein Manometer", - "it": "C’è un manometro", - "ru": "Есть манометр", - "pl": "Jest manometr", - "pt_BR": "Há um manômetro" - } + "question": { + "en": "What is the phone number of the maintainer?", + "nl": "Wat is het telefoonnummer van de beheerder?" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "render": "{phone}", + "id": "bike_repair_station-phone" }, { - "if": "manometer=no", - "then": { - "en": "There is no manometer", - "nl": "Er is geen luchtdrukmeter", - "fr": "Il n'y a pas de manomètre", - "gl": "Non hai manómetro", - "de": "Es gibt kein Manometer", - "it": "Non c’è un manometro", - "ru": "Нет манометра", - "pl": "Nie ma manometru", - "pt_BR": "Não há um manômetro" - } + "question": { + "nl": "Wanneer is dit fietsherstelpunt open?", + "en": "When is this bicycle repair point open?", + "fr": "Quand ce point de réparation de vélo est-il ouvert ?", + "it": "Quando è aperto questo punto riparazione bici?", + "de": "Wann ist diese Fahrradreparaturstelle geöffnet?", + "ru": "Когда работает эта точка обслуживания велосипедов?" + }, + "render": "{opening_hours_table()}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "nl": "Dag en nacht open", + "en": "Always open", + "fr": "Ouvert en permanence", + "it": "Sempre aperto", + "de": "Immer geöffnet", + "ru": "Всегда открыто", + "pt_BR": "Sempre aberto" + } + }, + { + "if": "opening_hours=", + "then": { + "nl": "Dag en nacht open", + "en": "Always open", + "fr": "Ouvert en permanence", + "it": "Sempre aperto", + "de": "Immer geöffnet", + "pt_BR": "Sempre aberto" + }, + "hideInAnswer": true + } + ], + "id": "bike_repair_station-opening_hours" }, { - "if": "manometer=broken", - "then": { - "en": "There is manometer but it is broken", - "nl": "Er is een luchtdrukmeter maar die is momenteel defect", - "fr": "Il y a un manomètre mais il est cassé", - "gl": "Hai manómetro pero está estragado", - "de": "Es gibt ein Manometer, aber es ist kaputt", - "it": "C’è un manometro ma è rotto", - "ru": "Есть манометр, но он сломан", - "pl": "Jest manometr, ale jest uszkodzony", - "pt_BR": "Há um manômetro mas está quebrado" - } - } - ] - }, - "level" - ], - "icon": { - "render": { - "en": "./assets/layers/bike_repair_station/repair_station.svg", - "ru": "./assets/layers/bike_repair_station/repair_station.svg", - "it": "./assets/layers/bike_repair_station/repair_station.svg", - "fi": "./assets/layers/bike_repair_station/repair_station.svg", - "fr": "./assets/layers/bike_repair_station/repair_station.svg", - "pt_BR": "./assets/layers/bike_repair_station/repair_station.svg" - }, - "mappings": [ - { - "if": { - "and": [ - "service:bicycle:pump=no", - "service:bicycle:pump:operational_status=broken" - ] + "id": "bike_repair_station-bike-chain-tool", + "question": { + "en": "Does this bike repair station have a special tool to repair your bike chain?", + "nl": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?", + "fr": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?", + "gl": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?", + "de": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?", + "it": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" + }, + "condition": "service:bicycle:tools=yes", + "mappings": [ + { + "if": "service:bicycle:chain_tool=yes", + "then": { + "en": "There is a chain tool", + "nl": "Er is een reparatieset voor je ketting", + "fr": "Il y a un outil pour réparer la chaine", + "gl": "Hai unha ferramenta para a cadea", + "de": "Es gibt ein Kettenwerkzeug", + "it": "È presente un utensile per riparare la catena", + "pt_BR": "Há uma ferramenta de corrente" + } + }, + { + "if": "service:bicycle:chain_tool=no", + "then": { + "en": "There is no chain tool", + "nl": "Er is geen reparatieset voor je ketting", + "fr": "Il n'y a pas d'outil pour réparer la chaine", + "gl": "Non hai unha ferramenta para a cadea", + "de": "Es gibt kein Kettenwerkzeug", + "it": "Non è presente un utensile per riparare la catena", + "pt_BR": "Não há uma ferramenta de corrente" + } + } + ] }, - "then": "./assets/layers/bike_repair_station/repair_station.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=yes" - ] + { + "id": "bike_repair_station-bike-stand", + "question": { + "en": "Does this bike station have a hook to hang your bike on or a stand to raise it?", + "nl": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?", + "fr": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?", + "gl": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?", + "de": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?", + "it": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" + }, + "condition": "service:bicycle:tools=yes", + "mappings": [ + { + "if": "service:bicycle:stand=yes", + "then": { + "en": "There is a hook or stand", + "nl": "Er is een haak of standaard", + "fr": "Il y a un crochet ou une accroche", + "gl": "Hai un guindastre ou soporte", + "de": "Es gibt einen Haken oder Ständer", + "it": "C’è un gancio o un supporto", + "pt_BR": "Há um gancho ou um suporte" + } + }, + { + "if": "service:bicycle:stand=no", + "then": { + "en": "There is no hook or stand", + "nl": "Er is geen haak of standaard", + "fr": "Il n'y pas de crochet ou d'accroche", + "gl": "Non hai un guindastre ou soporte", + "de": "Es gibt keinen Haken oder Ständer", + "it": "Non c’è né un gancio né un supporto", + "pt_BR": "Não há um gancho ou um suporte" + } + } + ] }, - "then": "./assets/layers/bike_repair_station/repair_station_pump.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump:operational_status=broken", - "service:bicycle:tools=no" - ] + { + "question": { + "en": "Is the bike pump still operational?", + "nl": "Werkt de fietspomp nog?", + "fr": "La pompe à vélo fonctionne-t-elle toujours ?", + "gl": "Segue a funcionar a bomba de ar?", + "de": "Ist die Fahrradpumpe noch funktionstüchtig?", + "it": "La pompa per bici è sempre funzionante?", + "ru": "Велосипедный насос все еще работает?", + "pl": "Czy pompka rowerowa jest nadal sprawna?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "service:bicycle:pump:operational_status=broken", + "then": { + "en": "The bike pump is broken", + "nl": "De fietspomp is kapot", + "fr": "La pompe à vélo est cassée", + "gl": "A bomba de ar está estragada", + "de": "Die Fahrradpumpe ist kaputt", + "it": "La pompa per bici è guasta", + "ru": "Велосипедный насос сломан", + "pl": "Pompka rowerowa jest zepsuta" + } + }, + { + "if": "service:bicycle:pump:operational_status=", + "then": { + "en": "The bike pump is operational", + "nl": "De fietspomp werkt nog", + "fr": "La pompe est opérationnelle", + "gl": "A bomba de ar está operativa", + "de": "Die Fahrradpumpe ist betriebsbereit", + "it": "La pompa per bici funziona", + "ru": "Велосипедный насос работает", + "pl": "Pompka rowerowa jest sprawna" + } + } + ], + "id": "Operational status" }, - "then": "./assets/layers/bike_repair_station/broken_pump_2.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", + { + "condition": { + "and": [ + "email~*", + "service:bicycle:pump:operational_status=broken" + ] + }, + "render": { + "en": "Report this bicycle pump as broken", + "nl": "Rapporteer deze fietspomp als kapot" + }, + "id": "Email maintainer" + }, + { + "question": { + "en": "What valves are supported?", + "nl": "Welke ventielen werken er met de pomp?", + "fr": "Quelles valves sont compatibles ?", + "gl": "Que válvulas son compatíbeis?", + "de": "Welche Ventile werden unterstützt?", + "it": "Quali valvole sono supportate?", + "pl": "Jakie zawory są obsługiwane?" + }, + "render": { + "en": "This pump supports the following valves: {valves}", + "nl": "Deze pomp werkt met de volgende ventielen: {valves}", + "fr": "Cette pompe est compatible avec les valves suivantes : {valves}", + "gl": "Esta bomba de ar admite as seguintes válvulas: {valves}", + "de": "Diese Pumpe unterstützt die folgenden Ventile: {valves}", + "it": "Questa pompa è compatibile con le seguenti valvole: {valves}", + "ru": "Этот насос поддерживает следующие клапаны: {valves}", + "pl": "Ta pompka obsługuje następujące zawory: {valves}" + }, + "freeform": { + "#addExtraTags": [ + "fixme=Freeform 'valves'-tag used: possibly a wrong value" + ], + "key": "valves" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "valves=sclaverand", + "then": { + "en": "Sclaverand (also known as Presta)", + "nl": "Sclaverand (ook gekend als Presta)", + "fr": "Sclaverand (aussi appelé Presta)", + "gl": "Sclaverand (tamén coñecido como Presta)", + "de": "Sklaverand (auch bekannt als Presta)", + "it": "Sclaverand (detta anche Presta)", + "ru": "Клапан Presta (также известный как французский клапан)" + } + }, + { + "if": "valves=dunlop", + "then": { + "en": "Dunlop", + "nl": "Dunlop", + "fr": "Dunlop", + "gl": "Dunlop", + "de": "Dunlop", + "it": "Dunlop", + "ru": "Клапан Dunlop" + } + }, + { + "if": "valves=schrader", + "then": { + "en": "Schrader (cars)", + "nl": "Schrader (auto's)", + "fr": "Schrader (les valves de voitures)", + "gl": "Schrader (para automóbiles)", + "de": "Schrader (Autos)", + "it": "Schrader (valvola delle auto)" + } + } + ], + "id": "bike_repair_station-valves" + }, + { + "id": "bike_repair_station-electrical_pump", + "question": { + "en": "Is this an electric bike pump?", + "nl": "Is dit een electrische fietspomp?", + "fr": "Est-ce que cette pompe est électrique ?", + "gl": "Esta é unha bomba de ar eléctrica?", + "de": "Ist dies eine elektrische Fahrradpumpe?", + "it": "Questa pompa per bici è elettrica?", + "ru": "Это электрический велосипедный насос?", + "pl": "Czy jest to elektryczna pompka do roweru?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "manual=yes", + "then": { + "en": "Manual pump", + "nl": "Manuele pomp", + "fr": "Pompe manuelle", + "gl": "Bomba de ar manual", + "de": "Manuelle Pumpe", + "it": "Pompa manuale", + "ru": "Ручной насос", + "pl": "Pompa ręczna", + "pt_BR": "Bomba manual" + } + }, + { + "if": "manual=no", + "then": { + "en": "Electrical pump", + "nl": "Electrische pomp", + "fr": "Pompe électrique", + "gl": "Bomba de ar eléctrica", + "de": "Elektrische Pumpe", + "it": "Pompa elettrica", + "ru": "Электрический насос", + "pl": "Pompka elektryczna", + "pt_BR": "Bomba elétrica" + } + } + ] + }, + { + "id": "bike_repair_station-manometer", + "question": { + "en": "Does the pump have a pressure indicator or manometer?", + "nl": "Heeft deze pomp een luchtdrukmeter?", + "fr": "Est-ce que la pompe à un manomètre integré ?", + "gl": "Ten a bomba de ar un indicador de presión ou un manómetro?", + "de": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?", + "it": "Questa pompa ha l’indicatore della pressione o il manometro?", + "pl": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "manometer=yes", + "then": { + "en": "There is a manometer", + "nl": "Er is een luchtdrukmeter", + "fr": "Il y a un manomètre", + "gl": "Hai manómetro", + "de": "Es gibt ein Manometer", + "it": "C’è un manometro", + "ru": "Есть манометр", + "pl": "Jest manometr", + "pt_BR": "Há um manômetro" + } + }, + { + "if": "manometer=no", + "then": { + "en": "There is no manometer", + "nl": "Er is geen luchtdrukmeter", + "fr": "Il n'y a pas de manomètre", + "gl": "Non hai manómetro", + "de": "Es gibt kein Manometer", + "it": "Non c’è un manometro", + "ru": "Нет манометра", + "pl": "Nie ma manometru", + "pt_BR": "Não há um manômetro" + } + }, + { + "if": "manometer=broken", + "then": { + "en": "There is manometer but it is broken", + "nl": "Er is een luchtdrukmeter maar die is momenteel defect", + "fr": "Il y a un manomètre mais il est cassé", + "gl": "Hai manómetro pero está estragado", + "de": "Es gibt ein Manometer, aber es ist kaputt", + "it": "C’è un manometro ma è rotto", + "ru": "Есть манометр, но он сломан", + "pl": "Jest manometr, ale jest uszkodzony", + "pt_BR": "Há um manômetro mas está quebrado" + } + } + ] + }, + "level" + ], + "icon": { + "render": { + "en": "./assets/layers/bike_repair_station/repair_station.svg", + "ru": "./assets/layers/bike_repair_station/repair_station.svg", + "it": "./assets/layers/bike_repair_station/repair_station.svg", + "fi": "./assets/layers/bike_repair_station/repair_station.svg", + "fr": "./assets/layers/bike_repair_station/repair_station.svg", + "pt_BR": "./assets/layers/bike_repair_station/repair_station.svg" + }, + "mappings": [ { - "or": [ - "service:bicycle:tools=no", - "service:bicycle:tools=" - ] + "if": { + "and": [ + "service:bicycle:pump=no", + "service:bicycle:pump:operational_status=broken" + ] + }, + "then": "./assets/layers/bike_repair_station/repair_station.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=yes" + ] + }, + "then": "./assets/layers/bike_repair_station/repair_station_pump.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump:operational_status=broken", + "service:bicycle:tools=no" + ] + }, + "then": "./assets/layers/bike_repair_station/broken_pump_2.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + { + "or": [ + "service:bicycle:tools=no", + "service:bicycle:tools=" + ] + } + ] + }, + "then": "./assets/layers/bike_repair_station/pump.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg", + "badge": true + } + ], + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#00f" + }, + "width": { + "render": "1" + }, + "wayHandling": 2, + "presets": [ + { + "title": { + "en": "Bike pump", + "nl": "Fietspomp", + "fr": "Pompe à vélo", + "gl": "Bomba de ar", + "de": "Fahrradpumpe", + "it": "Pompa per bici", + "ru": "Велосипедный насос", + "fi": "Pyöräpumppu", + "pl": "Pompka do roweru", + "pt_BR": "Bomba de bicicleta" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=no", + "service:bicycle:pump=yes" + ], + "description": { + "en": "A device to inflate your tires on a fixed location in the public space.

Examples of bicycle pumps

", + "nl": "Een apparaat waar je je fietsbanden kan oppompen, beschikbaar in de publieke ruimte. De fietspomp in je kelder telt dus niet.

Voorbeelden

Examples of bicycle pumps

", + "it": "Un dispositivo per gonfiare le proprie gomme in un luogo fisso pubblicamente accessibile.

Esempi di pompe per biciclette

", + "fr": "Un dispositif pour gonfler vos pneus sur un emplacement fixe dans l'espace public.

Exemples de pompes à vélo

", + "de": "Ein Gerät zum Aufpumpen von Reifen an einem festen Standort im öffentlichen Raum.

Beispiele für Fahrradpumpen

", + "pl": "Urządzenie do pompowania opon w stałym miejscu w przestrzeni publicznej.

Przykłady pompek rowerowych

", + "pt_BR": "Um dispositivo para encher seus pneus em um local fixa no espaço público

Exemplos de bombas de bicicletas

" } - ] }, - "then": "./assets/layers/bike_repair_station/pump.svg" - } + { + "title": { + "en": "Bike repair station and pump", + "nl": "Herstelpunt en pomp", + "fr": "Point de réparation vélo avec pompe", + "gl": "Estación de arranxo de bicicletas con bomba de ar", + "de": "Fahrrad-Reparaturstation und Pumpe", + "it": "Stazione di riparazione bici e pompa", + "pl": "Stacja naprawy rowerów i pompka" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=yes", + "service:bicycle:pump=yes" + ], + "description": { + "en": "A device with tools to repair your bike combined with a pump at a fixed location. The tools are often secured with chains against theft.

Example

", + "nl": "Een apparaat met zowel gereedschap om je fiets te herstellen, met een pomp. Deze zijn op een vastgemaakt op een plaats in de publieke ruimte, bv. aan een paal.

Voorbeeld

", + "fr": "Un dispositif avec des outils pour réparer votre vélo combiné à une pompe a un emplacement fixe. Les outils sont souvent attachés par une chaîne pour empêcher le vol.

Exemple

", + "it": "Un dispositivo con attrezzi per riparare la tua bici e una pompa in un luogo fisso. Gli attrezzi sono spesso attaccati ad una catena per prevenire il furto.

Esempio

", + "de": "Ein Gerät mit Werkzeugen zur Reparatur von Fahrrädern kombiniert mit einer Pumpe an einem festen Standort. Die Werkzeuge sind oft mit Ketten gegen Diebstahl gesichert.

Beispiel

" + } + }, + { + "title": { + "en": "Bike repair station without pump", + "nl": "Herstelpunt zonder pomp", + "fr": "Point de réparation vélo sans pompe", + "gl": "Estación de arranxo de bicicletas sin bomba de ar", + "de": "Fahrrad-Reparaturstation ohne Pumpe", + "it": "Stazione di riparazione bici senza pompa" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=yes", + "service:bicycle:pump=no" + ] + } ] - }, - "iconOverlays": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg", - "badge": true - } - ], - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#00f" - }, - "width": { - "render": "1" - }, - "wayHandling": 2, - "presets": [ - { - "title": { - "en": "Bike pump", - "nl": "Fietspomp", - "fr": "Pompe à vélo", - "gl": "Bomba de ar", - "de": "Fahrradpumpe", - "it": "Pompa per bici", - "ru": "Велосипедный насос", - "fi": "Pyöräpumppu", - "pl": "Pompka do roweru", - "pt_BR": "Bomba de bicicleta" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=no", - "service:bicycle:pump=yes" - ], - "description": { - "en": "A device to inflate your tires on a fixed location in the public space.

Examples of bicycle pumps

", - "nl": "Een apparaat waar je je fietsbanden kan oppompen, beschikbaar in de publieke ruimte. De fietspomp in je kelder telt dus niet.

Voorbeelden

Examples of bicycle pumps

", - "it": "Un dispositivo per gonfiare le proprie gomme in un luogo fisso pubblicamente accessibile.

Esempi di pompe per biciclette

", - "fr": "Un dispositif pour gonfler vos pneus sur un emplacement fixe dans l'espace public.

Exemples de pompes à vélo

", - "de": "Ein Gerät zum Aufpumpen von Reifen an einem festen Standort im öffentlichen Raum.

Beispiele für Fahrradpumpen

", - "pl": "Urządzenie do pompowania opon w stałym miejscu w przestrzeni publicznej.

Przykłady pompek rowerowych

", - "pt_BR": "Um dispositivo para encher seus pneus em um local fixa no espaço público

Exemplos de bombas de bicicletas

" - } - }, - { - "title": { - "en": "Bike repair station and pump", - "nl": "Herstelpunt en pomp", - "fr": "Point de réparation vélo avec pompe", - "gl": "Estación de arranxo de bicicletas con bomba de ar", - "de": "Fahrrad-Reparaturstation und Pumpe", - "it": "Stazione di riparazione bici e pompa", - "pl": "Stacja naprawy rowerów i pompka" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=yes", - "service:bicycle:pump=yes" - ], - "description": { - "en": "A device with tools to repair your bike combined with a pump at a fixed location. The tools are often secured with chains against theft.

Example

", - "nl": "Een apparaat met zowel gereedschap om je fiets te herstellen, met een pomp. Deze zijn op een vastgemaakt op een plaats in de publieke ruimte, bv. aan een paal.

Voorbeeld

", - "fr": "Un dispositif avec des outils pour réparer votre vélo combiné à une pompe a un emplacement fixe. Les outils sont souvent attachés par une chaîne pour empêcher le vol.

Exemple

", - "it": "Un dispositivo con attrezzi per riparare la tua bici e una pompa in un luogo fisso. Gli attrezzi sono spesso attaccati ad una catena per prevenire il furto.

Esempio

", - "de": "Ein Gerät mit Werkzeugen zur Reparatur von Fahrrädern kombiniert mit einer Pumpe an einem festen Standort. Die Werkzeuge sind oft mit Ketten gegen Diebstahl gesichert.

Beispiel

" - } - }, - { - "title": { - "en": "Bike repair station without pump", - "nl": "Herstelpunt zonder pomp", - "fr": "Point de réparation vélo sans pompe", - "gl": "Estación de arranxo de bicicletas sin bomba de ar", - "de": "Fahrrad-Reparaturstation ohne Pumpe", - "it": "Stazione di riparazione bici senza pompa" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=yes", - "service:bicycle:pump=no" - ] - } - ] } \ 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 5d230e2ec..d7930f854 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -1,680 +1,687 @@ { - "id": "bike_shop", - "name": { - "en": "Bike repair/shop", - "nl": "Fietszaak", - "fr": "Magasin ou réparateur de vélo", - "gl": "Tenda/arranxo de bicicletas", - "de": "Fahrradwerkstatt/geschäft", - "it": "Venditore/riparatore bici", - "ru": "Обслуживание велосипедов/магазин", - "pt_BR": "Reparo/loja de bicicletas" - }, - "minzoom": 13, - "source": { - "osmTags": { - "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", - "or": [ - "shop=bicycle", - { - "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", - "and": [ - "amenity=bicycle_rental", - "network=" - ] - }, - { - "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", - "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", - "and": [ - "shop=sports", - "service:bicycle:retail!=no", - "service:bicycle:repair!=no", - { - "or": [ - "sport=bicycle", - "sport=cycling", - "sport=" - ] - } - ] - }, - { - "#": "Any shop with any bicycle service", - "and": [ - "shop~*", - "service:bicycle:.*~~.*" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Bike repair/shop", - "nl": "Fietszaak", - "fr": "Magasin ou réparateur de vélo", - "gl": "Tenda/arranxo de bicicletas", - "de": "Fahrradwerkstatt/geschäft", - "it": "Venditore/riparatore bici", - "ru": "Обслуживание велосипедов/магазин", - "pt_BR": "Reparo/loja de bicicletas" - }, - "mappings": [ - { - "if": { - "and": [ - "shop=sports" - ] - }, - "then": { - "en": "Sport gear shop {name}", - "nl": "Sportwinkel {name}", - "fr": "Magasin de sport {name}", - "it": "Negozio di articoli sportivi {name}", - "ru": "Магазин спортивного инвентаря {name}", - "de": "Sportartikelgeschäft {name}", - "pt_BR": "Loja de equipamentos esportivos {name}" - } - }, - { - "if": { - "and": [ - "shop!~.*bicycle.*", - "shop~*" - ] - }, - "then": "Other shop" - }, - { - "if": { - "and": [ - { - "or": [ - "service:bicycle:rental=yes", - "amenity=bicycle_rental" - ] - } - ] - }, - "then": { - "nl": "Fietsverhuur {name}", - "en": "Bicycle rental {name}", - "fr": "Location de vélo {name}", - "it": "Noleggio di biciclette {name}", - "ru": "Прокат велосипедов {name}", - "de": "Fahrradverleih{name}", - "pt_BR": "Aluguel de bicicletas {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:retail!~yes", - "service:bicycle:repair=yes" - ] - }, - "then": { - "en": "Bike repair {name}", - "nl": "Fietsenmaker {name}", - "fr": "Réparateur de vélo {name}", - "gl": "Arranxo de bicicletas {name}", - "de": "Fahrradwerkstatt {name}", - "it": "Riparazione biciclette {name", - "ru": "Ремонт велосипедов {name}", - "pt_BR": "Reparo de bicicletas {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:repair!~yes" - ] - }, - "then": { - "en": "Bike shop {name}", - "nl": "Fietswinkel {name}", - "fr": "Magasin de vélo {name}", - "gl": "Tenda de bicicletas {name}", - "de": "Fahrradgeschäft {name}", - "it": "Negozio di biciclette {name}", - "ru": "Магазин велосипедов {name}", - "pt_BR": "Loja de bicicletas {name}" - } - }, - { - "if": "name~*", - "then": { - "en": "Bike repair/shop {name}", - "nl": "Fietszaak {name}", - "fr": "Magasin ou réparateur de vélo {name}", - "gl": "Tenda/arranxo de bicicletas {name}", - "de": "Fahrradwerkstatt/geschäft {name}", - "it": "Venditore/riparatore bici {name}", - "pt_BR": "Loja/reparo de bicicletas {name}" - } - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent" - }, - { - "condition": { - "or": [ - "service:bicycle:pump=yes", - "service:bicycle:pump=separate" - ] - }, - "render": "" - }, - { - "condition": "service:bicycle:diy=yes", - "render": "" - }, - "defaults" - ], - "description": { - "en": "A shop specifically selling bicycles or related items", - "nl": "Een winkel die hoofdzakelijk fietsen en fietstoebehoren verkoopt", - "fr": "Un magasin vendant spécifiquement des vélos ou des objets en lien", - "it": "Un negozio che vende specificatamente biciclette o articoli similari", - "ru": "Магазин, специализирующийся на продаже велосипедов или сопутствующих товаров", - "pt_BR": "Uma loja que vende especificamente bicicletas ou itens relacionados" - }, - "tagRenderings": [ - "images", - { - "condition": { - "and": [ - "shop~*", - "shop!~bicycle", - "shop!~sports" - ] - }, - "render": { - "en": "This shop is specialized in selling {shop} and does bicycle related activities", - "nl": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten.", - "fr": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo", - "it": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette", - "pt_BR": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" - } - }, - { - "question": { - "en": "What is the name of this bicycle shop?", - "nl": "Wat is de naam van deze fietszaak?", - "fr": "Quel est le nom du magasin de vélos ?", - "gl": "Cal é o nome desta tenda de bicicletas?", - "de": "Wie heißt dieser Fahrradladen?", - "it": "Qual è il nome di questo negozio di biciclette?", - "ru": "Как называется магазин велосипедов?", - "pt_BR": "Qual o nome desta loja de bicicletas?" - }, - "render": { - "en": "This bicycle shop is called {name}", - "nl": "Deze fietszaak heet {name}", - "fr": "Ce magasin s'appelle {name}", - "gl": "Esta tenda de bicicletas chámase {name}", - "de": "Dieses Fahrradgeschäft heißt {name}", - "it": "Questo negozio di biciclette è chiamato {name}", - "ru": "Этот магазин велосипедов называется {name}", - "pt_BR": "Esta loja de bicicletas se chama {nome}" - }, - "freeform": { - "key": "name" - } - }, - { - "question": { - "en": "What is the website of {name}?", - "nl": "Wat is de website van {name}?", - "fr": "Quel est le site web de {name} ?", - "gl": "Cal é a páxina web de {name}?", - "it": "Qual è il sito web di {name}?", - "ru": "Какой сайт у {name}?", - "id": "URL {name} apa?", - "de": "Was ist die Webseite von {name}?", - "pt_BR": "Qual o website de {name}?" - }, - "render": "{website}", - "freeform": { - "key": "website", - "type": "url" - } - }, - { - "question": { - "en": "What is the phone number of {name}?", - "nl": "Wat is het telefoonnummer van {name}?", - "fr": "Quel est le numéro de téléphone de {name} ?", - "gl": "Cal é o número de teléfono de {name}?", - "it": "Qual è il numero di telefono di {name}?", - "ru": "Какой номер телефона у {name}?", - "de": "Wie lautet die Telefonnummer von {name}?", - "pt_BR": "Qual o número de telefone de {name}?" - }, - "render": "{phone}", - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "en": "What is the email address of {name}?", - "nl": "Wat is het email-adres van {name}?", - "fr": "Quelle est l'adresse électronique de {name} ?", - "gl": "Cal é o enderezo de correo electrónico de {name}?", - "it": "Qual è l’indirizzo email di {name}?", - "ru": "Какой адрес электронной почты у {name}?", - "de": "Wie lautet die E-Mail-Adresse von {name}?", - "pt_BR": "Qual o endereço de email de {name}?" - }, - "render": "{email}", - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "render": "{opening_hours_table(opening_hours)}", - "question": "When is this shop opened?", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - } - }, - "description", - { - "render": "Enkel voor {access}", - "freeform": { - "key": "access" - } - }, - { - "question": { - "en": "Does this shop sell bikes?", - "nl": "Verkoopt deze fietszaak fietsen?", - "fr": "Est-ce que ce magasin vend des vélos ?", - "gl": "Esta tenda vende bicicletas?", - "de": "Verkauft dieser Laden Fahrräder?", - "it": "Questo negozio vende bici?", - "ru": "Продаются ли велосипеды в этом магазине?", - "pt_BR": "Esta loja vende bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:retail=yes", - "then": { - "en": "This shop sells bikes", - "nl": "Deze winkel verkoopt fietsen", - "fr": "Ce magasin vend des vélos", - "gl": "Esta tenda vende bicicletas", - "de": "Dieses Geschäft verkauft Fahrräder", - "it": "Questo negozio vende bici", - "ru": "В этом магазине продаются велосипеды", - "pt_BR": "Esta loja vende bicicletas" - } - }, - { - "if": "service:bicycle:retail=no", - "then": { - "en": "This shop doesn't sell bikes", - "nl": "Deze winkel verkoopt geen fietsen", - "fr": "Ce magasin ne vend pas de vélo", - "gl": "Esta tenda non vende bicicletas", - "de": "Dieses Geschäft verkauft keine Fahrräder", - "it": "Questo negozio non vende bici", - "ru": "В этом магазине не продают велосипеды", - "pt_BR": "Esta loja não vende bicicletas" - } - } - ] - }, - { - "question": { - "en": "Does this shop repair bikes?", - "nl": "Herstelt deze winkel fietsen?", - "fr": "Est-ce que ce magasin répare des vélos ?", - "gl": "Esta tenda arranxa bicicletas?", - "de": "Repariert dieses Geschäft Fahrräder?", - "it": "Questo negozio ripara bici?", - "ru": "В этом магазине ремонтируют велосипеды?", - "pt_BR": "Esta loja conserta bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:repair=yes", - "then": { - "en": "This shop repairs bikes", - "nl": "Deze winkel herstelt fietsen", - "fr": "Ce magasin répare des vélos", - "gl": "Esta tenda arranxa bicicletas", - "de": "Dieses Geschäft repariert Fahrräder", - "it": "Questo negozio ripara bici", - "ru": "Этот магазин ремонтирует велосипеды", - "pt_BR": "Esta loja conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=no", - "then": { - "en": "This shop doesn't repair bikes", - "nl": "Deze winkel herstelt geen fietsen", - "fr": "Ce magasin ne répare pas les vélos", - "gl": "Esta tenda non arranxa bicicletas", - "de": "Dieses Geschäft repariert keine Fahrräder", - "it": "Questo negozio non ripara bici", - "ru": "Этот магазин не ремонтирует велосипеды", - "pt_BR": "Esta loja não conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=only_sold", - "then": { - "en": "This shop only repairs bikes bought here", - "nl": "Deze winkel herstelt enkel fietsen die hier werden gekocht", - "fr": "Ce magasin ne répare seulement les vélos achetés là-bas", - "gl": "Esta tenda só arranxa bicicletas mercadas aquí", - "de": "Dieses Geschäft repariert nur hier gekaufte Fahrräder", - "it": "Questo negozio ripara solo le bici che sono state acquistate qua", - "ru": "Этот магазин ремонтирует только велосипеды, купленные здесь", - "pt_BR": "Esta loja conserta bicicletas compradas aqui" - } - }, - { - "if": "service:bicycle:repair=brand", - "then": { - "en": "This shop only repairs bikes of a certain brand", - "nl": "Deze winkel herstelt enkel fietsen van een bepaald merk", - "fr": "Ce magasin ne répare seulement des marques spécifiques", - "gl": "Esta tenda só arranxa bicicletas dunha certa marca", - "de": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke", - "it": "Questo negozio ripara solo le biciclette di una certa marca", - "ru": "В этом магазине обслуживают велосипеды определённого бренда", - "pt_BR": "Esta loja conserta bicicletas de uma certa marca" - } - } - ] - }, - { - "question": { - "en": "Does this shop rent out bikes?", - "nl": "Verhuurt deze winkel fietsen?", - "fr": "Est-ce ce magasin loue des vélos ?", - "gl": "Esta tenda aluga bicicletas?", - "de": "Vermietet dieser Laden Fahrräder?", - "it": "Questo negozio noleggia le bici?", - "ru": "Этот магазин сдает велосипеды в аренду?", - "pt_BR": "Esta loja aluga bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:rental=yes", - "then": { - "en": "This shop rents out bikes", - "nl": "Deze winkel verhuurt fietsen", - "fr": "Ce magasin loue des vélos", - "gl": "Esta tenda aluga bicicletas", - "de": "Dieses Geschäft vermietet Fahrräder", - "it": "Questo negozio noleggia le bici", - "ru": "Этот магазин сдает велосипеды в аренду", - "pt_BR": "Esta loja aluga bicicletas" - } - }, - { - "if": "service:bicycle:rental=no", - "then": { - "en": "This shop doesn't rent out bikes", - "nl": "Deze winkel verhuurt geen fietsen", - "fr": "Ce magasin ne loue pas de vélos", - "gl": "Esta tenda non aluga bicicletas", - "de": "Dieses Geschäft vermietet keine Fahrräder", - "it": "Questo negozio non noleggia le bici", - "ru": "Этот магазин не сдает велосипеды напрокат", - "pt_BR": "Esta loja não aluga bicicletas" - } - } - ] - }, - { - "question": { - "en": "Does this shop sell second-hand bikes?", - "nl": "Verkoopt deze winkel tweedehands fietsen?", - "fr": "Est-ce ce magasin vend des vélos d'occasion ?", - "gl": "Esta tenda vende bicicletas de segunda man?", - "de": "Verkauft dieses Geschäft gebrauchte Fahrräder?", - "it": "Questo negozio vende bici usate?", - "ru": "В этом магазине продаются подержанные велосипеды?" - }, - "mappings": [ - { - "if": "service:bicycle:second_hand=yes", - "then": { - "en": "This shop sells second-hand bikes", - "nl": "Deze winkel verkoopt tweedehands fietsen", - "fr": "Ce magasin vend des vélos d'occasion", - "gl": "Esta tenda vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft gebrauchte Fahrräder", - "it": "Questo negozio vende bici usate", - "ru": "В этом магазине продаются подержанные велосипеды" - } - }, - { - "if": "service:bicycle:second_hand=no", - "then": { - "en": "This shop doesn't sell second-hand bikes", - "nl": "Deze winkel verkoopt geen tweedehands fietsen", - "fr": "Ce magasin ne vend pas de vélos d'occasion", - "gl": "Esta tenda non vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft keine gebrauchten Fahrräder", - "it": "Questo negozio non vende bici usate", - "ru": "В этом магазине не продаются подержанные велосипеды" - } - }, - { - "if": "service:bicycle:second_hand=only", - "then": { - "en": "This shop only sells second-hand bikes", - "nl": "Deze winkel verkoopt enkel tweedehands fietsen", - "fr": "Ce magasin vend seulement des vélos d'occasion", - "gl": "Esta tenda só vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft nur gebrauchte Fahrräder", - "it": "Questo negozio vende solamente bici usate", - "ru": "В этом магазине продаются только подержанные велосипеды" - } - } - ] - }, - { - "question": { - "en": "Does this shop offer a bike pump for use by anyone?", - "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", - "fr": "Est-ce que ce magasin offre une pompe en accès libre ?", - "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", - "de": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?", - "it": "Questo negozio offre l’uso a chiunque di una pompa per bici?", - "ru": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" - }, - "mappings": [ - { - "if": "service:bicycle:pump=yes", - "then": { - "en": "This shop offers a bike pump for anyone", - "nl": "Deze winkel biedt een fietspomp aan voor iedereen", - "fr": "Ce magasin offre une pompe en acces libre", - "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", - "de": "Dieses Geschäft bietet eine Fahrradpumpe für alle an", - "it": "Questo negozio offre l’uso pubblico di una pompa per bici", - "ru": "В этом магазине есть велосипедный насос для всеобщего пользования" - } - }, - { - "if": "service:bicycle:pump=no", - "then": { - "en": "This shop doesn't offer a bike pump for anyone", - "nl": "Deze winkel biedt geen fietspomp aan voor eender wie", - "fr": "Ce magasin n'offre pas de pompe en libre accès", - "gl": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", - "de": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an", - "it": "Questo negozio non offre l’uso pubblico di una pompa per bici", - "ru": "В этом магазине нет велосипедного насоса для всеобщего пользования" - } - }, - { - "if": "service:bicycle:pump=separate", - "then": { - "en": "There is bicycle pump, it is shown as a separate point ", - "nl": "Er is een fietspomp, deze is apart aangeduid", - "fr": "Il y a une pompe à vélo, c'est indiqué comme un point séparé ", - "it": "C’è una pompa per bici, è mostrata come punto separato " - } - } - ] - }, - { - "question": { - "en": "Are there tools here to repair your own bike?", - "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", - "fr": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", - "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", - "it": "Sono presenti degli attrezzi per riparare la propria bici?", - "ru": "Есть ли здесь инструменты для починки собственного велосипеда?" - }, - "mappings": [ - { - "if": "service:bicycle:diy=yes", - "then": { - "en": "This shop offers tools for DIY repair", - "nl": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce magasin offre des outils pour réparer son vélo soi-même", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an", - "it": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" - } - }, - { - "if": "service:bicycle:diy=no", - "then": { - "en": "This shop doesn't offer tools for DIY repair", - "nl": "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", - "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an", - "it": "Questo negozio non offre degli attrezzi per la riparazione fai-da-te" - } - }, - { - "if": "service:bicycle:diy=only_sold", - "then": { - "en": "Tools for DIY repair are only available if you bought/hire the bike in the shop", - "nl": "Het gereedschap aan om je fiets zelf te herstellen is enkel voor als je de fiets er kocht of huurt", - "fr": "Des outils d'auto-réparation sont disponibles uniquement si vous avez acheté ou loué le vélo dans ce magasin", - "it": "Gli attrezzi per la riparazione fai-da-te sono disponibili solamente se hai acquistato/noleggiato la bici nel negozio", - "de": "Werkzeuge für die Selbstreparatur sind nur verfügbar, wenn Sie das Fahrrad im Laden gekauft/gemietet haben", - "ru": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" - } - } - ] - }, - { - "question": { - "en": "Are bicycles washed here?", - "nl": "Biedt deze winkel een fietsschoonmaak aan?", - "fr": "Lave-t-on les vélos ici ?", - "it": "Vengono lavate le bici qua?", - "ru": "Здесь моют велосипеды?", - "de": "Werden hier Fahrräder gewaschen?" - }, - "mappings": [ - { - "if": "service:bicycle:cleaning=yes", - "then": { - "en": "This shop cleans bicycles", - "nl": "Deze winkel biedt fietsschoonmaak aan", - "fr": "Ce magasin lave les vélos", - "it": "Questo negozio lava le biciclette", - "de": "Dieses Geschäft reinigt Fahrräder", - "ru": "В этом магазине оказываются услуги мойки/чистки велосипедов" - } - }, - { - "if": "service:bicycle:cleaning=diy", - "then": { - "en": "This shop has an installation where one can clean bicycles themselves", - "nl": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken", - "fr": "Ce magasin a une installation pour laver soi même des vélos", - "it": "Questo negozio ha una struttura dove è possibile pulire la propria bici", - "de": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" - } - }, - { - "if": "service:bicycle:cleaning=no", - "then": { - "en": "This shop doesn't offer bicycle cleaning", - "nl": "Deze winkel biedt geen fietsschoonmaak aan", - "fr": "Ce magasin ne fait pas le nettoyage de vélo", - "it": "Questo negozio non offre la pulizia della bicicletta", - "de": "Dieser Laden bietet keine Fahrradreinigung an", - "ru": "В этом магазине нет услуг мойки/чистки велосипедов" - } - } - ] - } - ], - "presets": [ - { - "title": { + "id": "bike_shop", + "name": { "en": "Bike repair/shop", "nl": "Fietszaak", - "fr": "Magasin et réparateur de vélo", + "fr": "Magasin ou réparateur de vélo", "gl": "Tenda/arranxo de bicicletas", "de": "Fahrradwerkstatt/geschäft", - "it": "Negozio/riparatore di bici", - "ru": "Обслуживание велосипедов/магазин" - }, - "tags": [ - "shop=bicycle" - ] - } - ], - "icon": { - "render": "./assets/layers/bike_shop/repair_shop.svg", - "mappings": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg" - }, - { - "if": "service:bicycle:retail=yes", - "then": "./assets/layers/bike_shop/shop.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "it": "Venditore/riparatore bici", + "ru": "Обслуживание велосипедов/магазин", + "pt_BR": "Reparo/loja de bicicletas" }, - { - "if": "service:bicycle:pump=yes", - "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#c00" - }, - "wayHandling": 2 + "minzoom": 13, + "source": { + "osmTags": { + "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", + "or": [ + "shop=bicycle", + { + "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", + "and": [ + "amenity=bicycle_rental", + "network=" + ] + }, + { + "#": "if sport is defined and is not bicycle, it is not matched; if bicycle retail/repair is marked as 'no', it is not shown to too.", + "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", + "and": [ + "shop=sports", + "service:bicycle:retail!=no", + "service:bicycle:repair!=no", + { + "or": [ + "sport=bicycle", + "sport=cycling", + "sport=" + ] + } + ] + } + ] + } + }, + "title": { + "render": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin ou réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft", + "it": "Venditore/riparatore bici", + "ru": "Обслуживание велосипедов/магазин", + "pt_BR": "Reparo/loja de bicicletas" + }, + "mappings": [ + { + "if": { + "and": [ + "shop=sports" + ] + }, + "then": { + "en": "Sport gear shop {name}", + "nl": "Sportwinkel {name}", + "fr": "Magasin de sport {name}", + "it": "Negozio di articoli sportivi {name}", + "ru": "Магазин спортивного инвентаря {name}", + "de": "Sportartikelgeschäft {name}", + "pt_BR": "Loja de equipamentos esportivos {name}" + } + }, + { + "if": { + "and": [ + "shop!~.*bicycle.*", + "shop~*" + ] + }, + "then": "Other shop" + }, + { + "if": { + "and": [ + { + "or": [ + "service:bicycle:rental=yes", + "amenity=bicycle_rental" + ] + } + ] + }, + "then": { + "nl": "Fietsverhuur {name}", + "en": "Bicycle rental {name}", + "fr": "Location de vélo {name}", + "it": "Noleggio di biciclette {name}", + "ru": "Прокат велосипедов {name}", + "de": "Fahrradverleih{name}", + "pt_BR": "Aluguel de bicicletas {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:retail!~yes", + "service:bicycle:repair=yes" + ] + }, + "then": { + "en": "Bike repair {name}", + "nl": "Fietsenmaker {name}", + "fr": "Réparateur de vélo {name}", + "gl": "Arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt {name}", + "it": "Riparazione biciclette {name", + "ru": "Ремонт велосипедов {name}", + "pt_BR": "Reparo de bicicletas {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:repair!~yes" + ] + }, + "then": { + "en": "Bike shop {name}", + "nl": "Fietswinkel {name}", + "fr": "Magasin de vélo {name}", + "gl": "Tenda de bicicletas {name}", + "de": "Fahrradgeschäft {name}", + "it": "Negozio di biciclette {name}", + "ru": "Магазин велосипедов {name}", + "pt_BR": "Loja de bicicletas {name}" + } + }, + { + "if": "name~*", + "then": { + "en": "Bike repair/shop {name}", + "nl": "Fietszaak {name}", + "fr": "Magasin ou réparateur de vélo {name}", + "gl": "Tenda/arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt/geschäft {name}", + "it": "Venditore/riparatore bici {name}", + "pt_BR": "Loja/reparo de bicicletas {name}" + } + } + ] + }, + "titleIcons": [ + { + "render": "", + "condition": "operator=De Fietsambassade Gent" + }, + { + "condition": { + "or": [ + "service:bicycle:pump=yes", + "service:bicycle:pump=separate" + ] + }, + "render": "" + }, + { + "condition": "service:bicycle:diy=yes", + "render": "" + }, + "defaults" + ], + "description": { + "en": "A shop specifically selling bicycles or related items", + "nl": "Een winkel die hoofdzakelijk fietsen en fietstoebehoren verkoopt", + "fr": "Un magasin vendant spécifiquement des vélos ou des objets en lien", + "it": "Un negozio che vende specificatamente biciclette o articoli similari", + "ru": "Магазин, специализирующийся на продаже велосипедов или сопутствующих товаров", + "pt_BR": "Uma loja que vende especificamente bicicletas ou itens relacionados" + }, + "tagRenderings": [ + "images", + { + "id": "bike_shop-is-bicycle_shop", + "condition": { + "and": [ + "shop~*", + "shop!~bicycle", + "shop!~sports" + ] + }, + "render": { + "en": "This shop is specialized in selling {shop} and does bicycle related activities", + "nl": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten.", + "fr": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo", + "it": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette", + "pt_BR": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" + } + }, + { + "question": { + "en": "What is the name of this bicycle shop?", + "nl": "Wat is de naam van deze fietszaak?", + "fr": "Quel est le nom du magasin de vélos ?", + "gl": "Cal é o nome desta tenda de bicicletas?", + "de": "Wie heißt dieser Fahrradladen?", + "it": "Qual è il nome di questo negozio di biciclette?", + "ru": "Как называется магазин велосипедов?", + "pt_BR": "Qual o nome desta loja de bicicletas?" + }, + "render": { + "en": "This bicycle shop is called {name}", + "nl": "Deze fietszaak heet {name}", + "fr": "Ce magasin s'appelle {name}", + "gl": "Esta tenda de bicicletas chámase {name}", + "de": "Dieses Fahrradgeschäft heißt {name}", + "it": "Questo negozio di biciclette è chiamato {name}", + "ru": "Этот магазин велосипедов называется {name}", + "pt_BR": "Esta loja de bicicletas se chama {nome}" + }, + "freeform": { + "key": "name" + }, + "id": "bike_shop-name" + }, + { + "question": { + "en": "What is the website of {name}?", + "nl": "Wat is de website van {name}?", + "fr": "Quel est le site web de {name} ?", + "gl": "Cal é a páxina web de {name}?", + "it": "Qual è il sito web di {name}?", + "ru": "Какой сайт у {name}?", + "id": "URL {name} apa?", + "de": "Was ist die Webseite von {name}?", + "pt_BR": "Qual o website de {name}?" + }, + "render": "{website}", + "freeform": { + "key": "website", + "type": "url" + }, + "id": "bike_shop-website" + }, + { + "question": { + "en": "What is the phone number of {name}?", + "nl": "Wat is het telefoonnummer van {name}?", + "fr": "Quel est le numéro de téléphone de {name} ?", + "gl": "Cal é o número de teléfono de {name}?", + "it": "Qual è il numero di telefono di {name}?", + "ru": "Какой номер телефона у {name}?", + "de": "Wie lautet die Telefonnummer von {name}?", + "pt_BR": "Qual o número de telefone de {name}?" + }, + "render": "{phone}", + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "bike_shop-phone" + }, + { + "question": { + "en": "What is the email address of {name}?", + "nl": "Wat is het email-adres van {name}?", + "fr": "Quelle est l'adresse électronique de {name} ?", + "gl": "Cal é o enderezo de correo electrónico de {name}?", + "it": "Qual è l’indirizzo email di {name}?", + "ru": "Какой адрес электронной почты у {name}?", + "de": "Wie lautet die E-Mail-Adresse von {name}?", + "pt_BR": "Qual o endereço de email de {name}?" + }, + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + }, + "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" + }, + "description", + { + "render": "Enkel voor {access}", + "freeform": { + "key": "access" + }, + "id": "bike_shop-access" + }, + { + "id": "bike_repair_sells-bikes", + "question": { + "en": "Does this shop sell bikes?", + "nl": "Verkoopt deze fietszaak fietsen?", + "fr": "Est-ce que ce magasin vend des vélos ?", + "gl": "Esta tenda vende bicicletas?", + "de": "Verkauft dieser Laden Fahrräder?", + "it": "Questo negozio vende bici?", + "ru": "Продаются ли велосипеды в этом магазине?", + "pt_BR": "Esta loja vende bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:retail=yes", + "then": { + "en": "This shop sells bikes", + "nl": "Deze winkel verkoopt fietsen", + "fr": "Ce magasin vend des vélos", + "gl": "Esta tenda vende bicicletas", + "de": "Dieses Geschäft verkauft Fahrräder", + "it": "Questo negozio vende bici", + "ru": "В этом магазине продаются велосипеды", + "pt_BR": "Esta loja vende bicicletas" + } + }, + { + "if": "service:bicycle:retail=no", + "then": { + "en": "This shop doesn't sell bikes", + "nl": "Deze winkel verkoopt geen fietsen", + "fr": "Ce magasin ne vend pas de vélo", + "gl": "Esta tenda non vende bicicletas", + "de": "Dieses Geschäft verkauft keine Fahrräder", + "it": "Questo negozio non vende bici", + "ru": "В этом магазине не продают велосипеды", + "pt_BR": "Esta loja não vende bicicletas" + } + } + ] + }, + { + "id": "bike_repair_repairs-bikes", + "question": { + "en": "Does this shop repair bikes?", + "nl": "Herstelt deze winkel fietsen?", + "fr": "Est-ce que ce magasin répare des vélos ?", + "gl": "Esta tenda arranxa bicicletas?", + "de": "Repariert dieses Geschäft Fahrräder?", + "it": "Questo negozio ripara bici?", + "ru": "В этом магазине ремонтируют велосипеды?", + "pt_BR": "Esta loja conserta bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:repair=yes", + "then": { + "en": "This shop repairs bikes", + "nl": "Deze winkel herstelt fietsen", + "fr": "Ce magasin répare des vélos", + "gl": "Esta tenda arranxa bicicletas", + "de": "Dieses Geschäft repariert Fahrräder", + "it": "Questo negozio ripara bici", + "ru": "Этот магазин ремонтирует велосипеды", + "pt_BR": "Esta loja conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=no", + "then": { + "en": "This shop doesn't repair bikes", + "nl": "Deze winkel herstelt geen fietsen", + "fr": "Ce magasin ne répare pas les vélos", + "gl": "Esta tenda non arranxa bicicletas", + "de": "Dieses Geschäft repariert keine Fahrräder", + "it": "Questo negozio non ripara bici", + "ru": "Этот магазин не ремонтирует велосипеды", + "pt_BR": "Esta loja não conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=only_sold", + "then": { + "en": "This shop only repairs bikes bought here", + "nl": "Deze winkel herstelt enkel fietsen die hier werden gekocht", + "fr": "Ce magasin ne répare seulement les vélos achetés là-bas", + "gl": "Esta tenda só arranxa bicicletas mercadas aquí", + "de": "Dieses Geschäft repariert nur hier gekaufte Fahrräder", + "it": "Questo negozio ripara solo le bici che sono state acquistate qua", + "ru": "Этот магазин ремонтирует только велосипеды, купленные здесь", + "pt_BR": "Esta loja conserta bicicletas compradas aqui" + } + }, + { + "if": "service:bicycle:repair=brand", + "then": { + "en": "This shop only repairs bikes of a certain brand", + "nl": "Deze winkel herstelt enkel fietsen van een bepaald merk", + "fr": "Ce magasin ne répare seulement des marques spécifiques", + "gl": "Esta tenda só arranxa bicicletas dunha certa marca", + "de": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke", + "it": "Questo negozio ripara solo le biciclette di una certa marca", + "ru": "В этом магазине обслуживают велосипеды определённого бренда", + "pt_BR": "Esta loja conserta bicicletas de uma certa marca" + } + } + ] + }, + { + "id": "bike_repair_rents-bikes", + "question": { + "en": "Does this shop rent out bikes?", + "nl": "Verhuurt deze winkel fietsen?", + "fr": "Est-ce ce magasin loue des vélos ?", + "gl": "Esta tenda aluga bicicletas?", + "de": "Vermietet dieser Laden Fahrräder?", + "it": "Questo negozio noleggia le bici?", + "ru": "Этот магазин сдает велосипеды в аренду?", + "pt_BR": "Esta loja aluga bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:rental=yes", + "then": { + "en": "This shop rents out bikes", + "nl": "Deze winkel verhuurt fietsen", + "fr": "Ce magasin loue des vélos", + "gl": "Esta tenda aluga bicicletas", + "de": "Dieses Geschäft vermietet Fahrräder", + "it": "Questo negozio noleggia le bici", + "ru": "Этот магазин сдает велосипеды в аренду", + "pt_BR": "Esta loja aluga bicicletas" + } + }, + { + "if": "service:bicycle:rental=no", + "then": { + "en": "This shop doesn't rent out bikes", + "nl": "Deze winkel verhuurt geen fietsen", + "fr": "Ce magasin ne loue pas de vélos", + "gl": "Esta tenda non aluga bicicletas", + "de": "Dieses Geschäft vermietet keine Fahrräder", + "it": "Questo negozio non noleggia le bici", + "ru": "Этот магазин не сдает велосипеды напрокат", + "pt_BR": "Esta loja não aluga bicicletas" + } + } + ] + }, + { + "id": "bike_repair_second-hand-bikes", + "question": { + "en": "Does this shop sell second-hand bikes?", + "nl": "Verkoopt deze winkel tweedehands fietsen?", + "fr": "Est-ce ce magasin vend des vélos d'occasion ?", + "gl": "Esta tenda vende bicicletas de segunda man?", + "de": "Verkauft dieses Geschäft gebrauchte Fahrräder?", + "it": "Questo negozio vende bici usate?", + "ru": "В этом магазине продаются подержанные велосипеды?" + }, + "mappings": [ + { + "if": "service:bicycle:second_hand=yes", + "then": { + "en": "This shop sells second-hand bikes", + "nl": "Deze winkel verkoopt tweedehands fietsen", + "fr": "Ce magasin vend des vélos d'occasion", + "gl": "Esta tenda vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft gebrauchte Fahrräder", + "it": "Questo negozio vende bici usate", + "ru": "В этом магазине продаются подержанные велосипеды" + } + }, + { + "if": "service:bicycle:second_hand=no", + "then": { + "en": "This shop doesn't sell second-hand bikes", + "nl": "Deze winkel verkoopt geen tweedehands fietsen", + "fr": "Ce magasin ne vend pas de vélos d'occasion", + "gl": "Esta tenda non vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft keine gebrauchten Fahrräder", + "it": "Questo negozio non vende bici usate", + "ru": "В этом магазине не продаются подержанные велосипеды" + } + }, + { + "if": "service:bicycle:second_hand=only", + "then": { + "en": "This shop only sells second-hand bikes", + "nl": "Deze winkel verkoopt enkel tweedehands fietsen", + "fr": "Ce magasin vend seulement des vélos d'occasion", + "gl": "Esta tenda só vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft nur gebrauchte Fahrräder", + "it": "Questo negozio vende solamente bici usate", + "ru": "В этом магазине продаются только подержанные велосипеды" + } + } + ] + }, + { + "id": "bike_repair_bike-pump-service", + "question": { + "en": "Does this shop offer a bike pump for use by anyone?", + "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", + "fr": "Est-ce que ce magasin offre une pompe en accès libre ?", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", + "de": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?", + "it": "Questo negozio offre l’uso a chiunque di una pompa per bici?", + "ru": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" + }, + "mappings": [ + { + "if": "service:bicycle:pump=yes", + "then": { + "en": "This shop offers a bike pump for anyone", + "nl": "Deze winkel biedt een fietspomp aan voor iedereen", + "fr": "Ce magasin offre une pompe en acces libre", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet eine Fahrradpumpe für alle an", + "it": "Questo negozio offre l’uso pubblico di una pompa per bici", + "ru": "В этом магазине есть велосипедный насос для всеобщего пользования" + } + }, + { + "if": "service:bicycle:pump=no", + "then": { + "en": "This shop doesn't offer a bike pump for anyone", + "nl": "Deze winkel biedt geen fietspomp aan voor eender wie", + "fr": "Ce magasin n'offre pas de pompe en libre accès", + "gl": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an", + "it": "Questo negozio non offre l’uso pubblico di una pompa per bici", + "ru": "В этом магазине нет велосипедного насоса для всеобщего пользования" + } + }, + { + "if": "service:bicycle:pump=separate", + "then": { + "en": "There is bicycle pump, it is shown as a separate point ", + "nl": "Er is een fietspomp, deze is apart aangeduid", + "fr": "Il y a une pompe à vélo, c'est indiqué comme un point séparé ", + "it": "C’è una pompa per bici, è mostrata come punto separato " + } + } + ] + }, + { + "id": "bike_repair_tools-service", + "question": { + "en": "Are there tools here to repair your own bike?", + "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", + "fr": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", + "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", + "it": "Sono presenti degli attrezzi per riparare la propria bici?", + "ru": "Есть ли здесь инструменты для починки собственного велосипеда?" + }, + "mappings": [ + { + "if": "service:bicycle:diy=yes", + "then": { + "en": "This shop offers tools for DIY repair", + "nl": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin offre des outils pour réparer son vélo soi-même", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an", + "it": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" + } + }, + { + "if": "service:bicycle:diy=no", + "then": { + "en": "This shop doesn't offer tools for DIY repair", + "nl": "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", + "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an", + "it": "Questo negozio non offre degli attrezzi per la riparazione fai-da-te" + } + }, + { + "if": "service:bicycle:diy=only_sold", + "then": { + "en": "Tools for DIY repair are only available if you bought/hire the bike in the shop", + "nl": "Het gereedschap aan om je fiets zelf te herstellen is enkel voor als je de fiets er kocht of huurt", + "fr": "Des outils d'auto-réparation sont disponibles uniquement si vous avez acheté ou loué le vélo dans ce magasin", + "it": "Gli attrezzi per la riparazione fai-da-te sono disponibili solamente se hai acquistato/noleggiato la bici nel negozio", + "de": "Werkzeuge für die Selbstreparatur sind nur verfügbar, wenn Sie das Fahrrad im Laden gekauft/gemietet haben", + "ru": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" + } + } + ] + }, + { + "id": "bike_repair_bike-wash", + "question": { + "en": "Are bicycles washed here?", + "nl": "Biedt deze winkel een fietsschoonmaak aan?", + "fr": "Lave-t-on les vélos ici ?", + "it": "Vengono lavate le bici qua?", + "ru": "Здесь моют велосипеды?", + "de": "Werden hier Fahrräder gewaschen?" + }, + "mappings": [ + { + "if": "service:bicycle:cleaning=yes", + "then": { + "en": "This shop cleans bicycles", + "nl": "Deze winkel biedt fietsschoonmaak aan", + "fr": "Ce magasin lave les vélos", + "it": "Questo negozio lava le biciclette", + "de": "Dieses Geschäft reinigt Fahrräder", + "ru": "В этом магазине оказываются услуги мойки/чистки велосипедов" + } + }, + { + "if": "service:bicycle:cleaning=diy", + "then": { + "en": "This shop has an installation where one can clean bicycles themselves", + "nl": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken", + "fr": "Ce magasin a une installation pour laver soi même des vélos", + "it": "Questo negozio ha una struttura dove è possibile pulire la propria bici", + "de": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" + } + }, + { + "if": "service:bicycle:cleaning=no", + "then": { + "en": "This shop doesn't offer bicycle cleaning", + "nl": "Deze winkel biedt geen fietsschoonmaak aan", + "fr": "Ce magasin ne fait pas le nettoyage de vélo", + "it": "Questo negozio non offre la pulizia della bicicletta", + "de": "Dieser Laden bietet keine Fahrradreinigung an", + "ru": "В этом магазине нет услуг мойки/чистки велосипедов" + } + } + ] + } + ], + "presets": [ + { + "title": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin et réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft", + "it": "Negozio/riparatore di bici", + "ru": "Обслуживание велосипедов/магазин" + }, + "tags": [ + "shop=bicycle" + ] + } + ], + "icon": { + "render": "./assets/layers/bike_shop/repair_shop.svg", + "mappings": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg" + }, + { + "if": "service:bicycle:retail=yes", + "then": "./assets/layers/bike_shop/shop.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + }, + { + "if": "service:bicycle:pump=yes", + "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#c00" + }, + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bike_themed_object/bike_themed_object.json b/assets/layers/bike_themed_object/bike_themed_object.json index bae9e790e..527376742 100644 --- a/assets/layers/bike_themed_object/bike_themed_object.json +++ b/assets/layers/bike_themed_object/bike_themed_object.json @@ -1,73 +1,73 @@ { - "id": "bike_themed_object", - "name": { - "en": "Bike related object", - "nl": "Fietsgerelateerd object", - "fr": "Objet cycliste", - "de": "Mit Fahrrad zusammenhängendes Objekt", - "it": "Oggetto relativo alle bici" - }, - "minzoom": 13, - "source": { - "osmTags": { - "or": [ - "theme=bicycle", - "theme=cycling", - "sport=cycling", - "association=cycling", - "association=bicycle", - "ngo=cycling", - "ngo=bicycle", - "club=bicycle", - "club=cycling" - ] - } - }, - "title": { - "render": { - "en": "Bike related object", - "nl": "Fietsgerelateerd object", - "fr": "Objet cycliste", - "de": "Mit Fahrrad zusammenhängendes Objekt", - "it": "Oggetto relativo alle bici" + "id": "bike_themed_object", + "name": { + "en": "Bike related object", + "nl": "Fietsgerelateerd object", + "fr": "Objet cycliste", + "de": "Mit Fahrrad zusammenhängendes Objekt", + "it": "Oggetto relativo alle bici" }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - }, - { - "if": "leisure=track", - "then": { - "nl": "Wielerpiste", - "en": "Cycle track", - "fr": "Piste cyclable", - "it": "Pista ciclabile", - "de": "Radweg" + "minzoom": 13, + "source": { + "osmTags": { + "or": [ + "theme=bicycle", + "theme=cycling", + "sport=cycling", + "association=cycling", + "association=bicycle", + "ngo=cycling", + "ngo=bicycle", + "club=bicycle", + "club=cycling" + ] } - } - ] - }, - "tagRenderings": [ - "images", - "description", - "website", - "email", - "phone", - "opening_hours" - ], - "icon": { - "render": "./assets/layers/bike_themed_object/other_services.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#AB76D5" - }, - "presets": [], - "wayHandling": 2 + }, + "title": { + "render": { + "en": "Bike related object", + "nl": "Fietsgerelateerd object", + "fr": "Objet cycliste", + "de": "Mit Fahrrad zusammenhängendes Objekt", + "it": "Oggetto relativo alle bici" + }, + "mappings": [ + { + "if": "name~*", + "then": "{name}" + }, + { + "if": "leisure=track", + "then": { + "nl": "Wielerpiste", + "en": "Cycle track", + "fr": "Piste cyclable", + "it": "Pista ciclabile", + "de": "Radweg" + } + } + ] + }, + "tagRenderings": [ + "images", + "description", + "website", + "email", + "phone", + "opening_hours" + ], + "icon": { + "render": "./assets/layers/bike_themed_object/other_services.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#AB76D5" + }, + "presets": [], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/binocular/binocular.json b/assets/layers/binocular/binocular.json index 3c31bcfac..46ba8fe42 100644 --- a/assets/layers/binocular/binocular.json +++ b/assets/layers/binocular/binocular.json @@ -1,102 +1,104 @@ { - "id": "binocular", - "name": { - "en": "Binoculars", - "nl": "Verrekijkers" - }, - "minzoom": 0, - "title": { - "render": { - "en": "Binoculars", - "nl": "Verrekijker" - } - }, - "description": { - "en": "Binoculas", - "nl": "Verrekijkers" - }, - "tagRenderings": [ - "images", - { - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "en": "Free to use", - "nl": "Gratis te gebruiken" - } - } - ], - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "render": { - "en": "Using these binoculars costs {charge}", - "nl": "Deze verrekijker gebruiken kost {charge}" - }, - "question": { - "en": "How much does one have to pay to use these binoculars?", - "nl": "Hoeveel moet men betalen om deze verrekijker te gebruiken?" - } + "id": "binocular", + "name": { + "en": "Binoculars", + "nl": "Verrekijkers" }, - { - "question": { - "en": "When looking through this binocular, in what direction does one look?", - "nl": "Welke richting kijkt men uit als men door deze verrekijker kijkt?" - }, - "render": { - "en": "Looks towards {direction}°", - "nl": "Kijkt richting {direction}°" - }, - "freeform": { - "key": "direction", - "type": "direction" - } + "minzoom": 0, + "title": { + "render": { + "en": "Binoculars", + "nl": "Verrekijker" + } + }, + "description": { + "en": "Binoculas", + "nl": "Verrekijkers" + }, + "tagRenderings": [ + "images", + { + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Free to use", + "nl": "Gratis te gebruiken" + } + } + ], + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "render": { + "en": "Using these binoculars costs {charge}", + "nl": "Deze verrekijker gebruiken kost {charge}" + }, + "question": { + "en": "How much does one have to pay to use these binoculars?", + "nl": "Hoeveel moet men betalen om deze verrekijker te gebruiken?" + }, + "id": "binocular-charge" + }, + { + "question": { + "en": "When looking through this binocular, in what direction does one look?", + "nl": "Welke richting kijkt men uit als men door deze verrekijker kijkt?" + }, + "render": { + "en": "Looks towards {direction}°", + "nl": "Kijkt richting {direction}°" + }, + "freeform": { + "key": "direction", + "type": "direction" + }, + "id": "binocular-direction" + } + ], + "icon": { + "render": "circle:white;./assets/layers/binocular/telescope.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=binoculars" + ], + "title": { + "en": "binoculars", + "nl": "verrekijker" + }, + "description": { + "en": "A telescope or pair of binoculars mounted on a pole, available to the public to look around. ", + "nl": "Een telescoop of verrekijker die op een vaste plaats gemonteerd staat waar iedereen door mag kijken. " + }, + "preciseInput": { + "preferredBackground": "photo" + } + } + ], + "source": { + "osmTags": { + "and": [ + "amenity=binoculars" + ] + } } - ], - "icon": { - "render": "circle:white;./assets/layers/binocular/telescope.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=binoculars" - ], - "title": { - "en": "binoculars", - "nl": "verrekijker" - }, - "description": { - "en": "A telescope or pair of binoculars mounted on a pole, available to the public to look around. ", - "nl": "Een telescoop of verrekijker die op een vaste plaats gemonteerd staat waar iedereen door mag kijken. " - }, - "preciseInput": { - "preferredBackground": "photo" - } - } - ], - "source": { - "osmTags": { - "and": [ - "amenity=binoculars" - ] - } - } } \ No newline at end of file diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index 50fce43cb..38f8e1970 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -1,295 +1,300 @@ { - "id": "birdhide", - "name": { - "nl": "Vogelkijkhutten" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "leisure=bird_hide" - ] - } - }, - "title": { - "render": { - "nl": "Vogelkijkplaats" + "id": "birdhide", + "name": { + "nl": "Vogelkijkhutten" }, - "mappings": [ - { - "if": { - "and": [ - "name~((V|v)ogel.*).*" - ] - }, - "then": { - "nl": "{name}" + "minzoom": 14, + "source": { + "osmTags": { + "and": [ + "leisure=bird_hide" + ] } - }, - { - "if": { - "and": [ - "name~*", + }, + "title": { + "render": { + "nl": "Vogelkijkplaats" + }, + "mappings": [ { - "or": [ - "building!~no", - "shelter=yes" - ] + "if": { + "and": [ + "name~((V|v)ogel.*).*" + ] + }, + "then": { + "nl": "{name}" + } + }, + { + "if": { + "and": [ + "name~*", + { + "or": [ + "building!~no", + "shelter=yes" + ] + } + ] + }, + "then": { + "nl": "Vogelkijkhut {name}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "Vogelkijkwand {name}" + } } - ] + ] + }, + "description": { + "nl": "Een vogelkijkhut" + }, + "tagRenderings": [ + "images", + { + "id": "bird-hide-shelter-or-wall", + "question": { + "nl": "Is dit een kijkwand of kijkhut?" + }, + "mappings": [ + { + "if": { + "and": [ + "shelter=no", + "building=", + "amenity=" + ] + }, + "then": { + "nl": "Vogelkijkwand" + } + }, + { + "if": { + "and": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + } + }, + { + "if": { + "and": [ + "building=tower", + "bird_hide=tower" + ] + }, + "then": { + "nl": "Vogelkijktoren" + } + }, + { + "if": { + "or": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + }, + "hideInAnswer": true + } + ] }, - "then": { - "nl": "Vogelkijkhut {name}" - } - }, - { - "if": { - "and": [ - "name~*" - ] + { + "id": "bird-hide-wheelchair", + "question": { + "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" + }, + "mappings": [ + { + "if": { + "and": [ + "wheelchair=designated" + ] + }, + "then": { + "nl": "Er zijn speciale voorzieningen voor rolstoelen" + } + }, + { + "if": { + "and": [ + "wheelchair=yes" + ] + }, + "then": { + "nl": "Een rolstoel raakt er vlot" + } + }, + { + "if": { + "and": [ + "wheelchair=limited" + ] + }, + "then": { + "nl": "Je kan er raken met een rolstoel, maar het is niet makkelijk" + } + }, + { + "if": { + "and": [ + "wheelchair=no" + ] + }, + "then": { + "nl": "Niet rolstoeltoegankelijk" + } + } + ] }, - "then": { - "nl": "Vogelkijkwand {name}" + { + "render": { + "nl": "Beheer door {operator}" + }, + "freeform": { + "key": "operator" + }, + "question": { + "nl": "Wie beheert deze vogelkijkplaats?" + }, + "mappings": [ + { + "if": "operator=Natuurpunt", + "then": { + "nl": "Beheer door Natuurpunt" + } + }, + { + "if": "operator=Agentschap Natuur en Bos", + "then": { + "nl": "Beheer door het Agentschap Natuur en Bos " + } + } + ], + "id": "birdhide-operator" + } + ], + "icon": { + "render": { + "nl": "./assets/layers/birdhide/birdhide.svg" + }, + "mappings": [ + { + "if": { + "or": [ + "building=yes", + "shelter=yes", + "amenity=shelter" + ] + }, + "then": "./assets/layers/birdhide/birdshelter.svg" + } + ] + }, + "size": { + "freeform": { + "addExtraTags": [] + }, + "render": { + "nl": "40,40,center" + }, + "mappings": [] + }, + "color": { + "render": { + "nl": "#94bb28" + } + }, + "stroke": { + "render": { + "nl": "3" + } + }, + "presets": [ + { + "tags": [ + "leisure=bird_hide", + "building=yes", + "shelter=yes", + "amenity=shelter" + ], + "title": { + "nl": "vogelkijkhut" + }, + "description": { + "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" + } + }, + { + "tags": [ + "leisure=bird_hide", + "building=no", + "shelter=no" + ], + "title": { + "nl": "vogelkijkwand" + }, + "description": { + "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" + } + } + ], + "wayHandling": 1, + "filter": [ + { + "id": "wheelchair", + "options": [ + { + "question": { + "nl": "Rolstoeltoegankelijk", + "en": "Wheelchair accessible" + }, + "osmTags": { + "or": [ + "wheelchair=yes", + "wheelchair=designated", + "wheelchair=permissive" + ] + } + } + ] + }, + { + "id": "shelter", + "options": [ + { + "question": { + "nl": "Enkel overdekte kijkhutten" + }, + "osmTags": { + "and": [ + { + "or": [ + "shelter=yes", + "building~*" + ] + }, + "covered!=no" + ] + } + } + ] } - } ] - }, - "description": { - "nl": "Een vogelkijkhut" - }, - "tagRenderings": [ - "images", - { - "question": { - "nl": "Is dit een kijkwand of kijkhut?" - }, - "mappings": [ - { - "if": { - "and": [ - "shelter=no", - "building=", - "amenity=" - ] - }, - "then": { - "nl": "Vogelkijkwand" - } - }, - { - "if": { - "and": [ - "amenity=shelter", - "building=yes", - "shelter=yes" - ] - }, - "then": { - "nl": "Vogelkijkhut" - } - }, - { - "if": { - "and": [ - "building=tower", - "bird_hide=tower" - ] - }, - "then": { - "nl": "Vogelkijktoren" - } - }, - { - "if": { - "or": [ - "amenity=shelter", - "building=yes", - "shelter=yes" - ] - }, - "then": { - "nl": "Vogelkijkhut" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" - }, - "mappings": [ - { - "if": { - "and": [ - "wheelchair=designated" - ] - }, - "then": { - "nl": "Er zijn speciale voorzieningen voor rolstoelen" - } - }, - { - "if": { - "and": [ - "wheelchair=yes" - ] - }, - "then": { - "nl": "Een rolstoel raakt er vlot" - } - }, - { - "if": { - "and": [ - "wheelchair=limited" - ] - }, - "then": { - "nl": "Je kan er raken met een rolstoel, maar het is niet makkelijk" - } - }, - { - "if": { - "and": [ - "wheelchair=no" - ] - }, - "then": { - "nl": "Niet rolstoeltoegankelijk" - } - } - ] - }, - { - "render": { - "nl": "Beheer door {operator}" - }, - "freeform": { - "key": "operator" - }, - "question": { - "nl": "Wie beheert deze vogelkijkplaats?" - }, - "mappings": [ - { - "if": "operator=Natuurpunt", - "then": { - "nl": "Beheer door Natuurpunt" - } - }, - { - "if": "operator=Agentschap Natuur en Bos", - "then": { - "nl": "Beheer door het Agentschap Natuur en Bos " - } - } - ] - } - ], - "icon": { - "render": { - "nl": "./assets/layers/birdhide/birdhide.svg" - }, - "mappings": [ - { - "if": { - "or": [ - "building=yes", - "shelter=yes", - "amenity=shelter" - ] - }, - "then": "./assets/layers/birdhide/birdshelter.svg" - } - ] - }, - "size": { - "freeform": { - "addExtraTags": [] - }, - "render": { - "nl": "40,40,center" - }, - "mappings": [] - }, - "color": { - "render": { - "nl": "#94bb28" - } - }, - "stroke": { - "render": { - "nl": "3" - } - }, - "presets": [ - { - "tags": [ - "leisure=bird_hide", - "building=yes", - "shelter=yes", - "amenity=shelter" - ], - "title": { - "nl": "Vogelkijkhut" - }, - "description": { - "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" - } - }, - { - "tags": [ - "leisure=bird_hide", - "building=no", - "shelter=no" - ], - "title": { - "nl": "Vogelkijkwand" - }, - "description": { - "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" - } - } - ], - "wayHandling": 1, - "filter": [ - { - "options": [ - { - "question": { - "nl": "Rolstoeltoegankelijk", - "en": "Wheelchair accessible" - }, - "osmTags": { - "or": [ - "wheelchair=yes", - "wheelchair=designated", - "wheelchair=permissive" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "nl": "Enkel overdekte kijkhutten" - }, - "osmTags": { - "and": [ - { - "or": [ - "shelter=yes", - "building~*" - ] - }, - "covered!=no" - ] - } - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/cafe_pub/cafe_pub.json b/assets/layers/cafe_pub/cafe_pub.json index db93b4f8f..e5977e8bb 100644 --- a/assets/layers/cafe_pub/cafe_pub.json +++ b/assets/layers/cafe_pub/cafe_pub.json @@ -1,184 +1,185 @@ { - "id": "cafe_pub", - "name": { - "nl": "Cafés", - "en": "Cafés and pubs" - }, - "source": { - "osmTags": { - "or": [ - "amenity=bar", - "amenity=pub", - "amenity=cafe", - "amenity=biergarten" - ] - } - }, - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/cafe_pub/pub.svg", - "mappings": [ - { - "if": "amenity=cafe", - "then": "circle:white;./assets/layers/cafe_pub/cafe.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true - } - ], - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "presets": [ - { - "tags": [ - "amenity=pub" - ], - "title": { - "en": "pub", - "nl": "bruin cafe of kroeg" - }, - "description": { - "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " - }, - "preciseInput": { - "preferredBackground": "map" - } + "id": "cafe_pub", + "name": { + "nl": "Cafés", + "en": "Cafés and pubs" }, - { - "tags": [ - "amenity=bar" - ], - "title": { - "en": "bar", - "nl": "bar" - }, - "description": { - "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" - }, - "preciseInput": { - "preferredBackground": "map" - } - }, - { - "tags": [ - "amenity=cafe" - ], - "title": { - "en": "cafe", - "nl": "cafe" - }, - "description": { - "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "title": { - "render": { - "nl": "Café" - }, - "mappings": [ - { - "if": { - "and": [ - "name~*" - ] - }, - "then": { - "nl": "{name}", - "en": "{name}" + "source": { + "osmTags": { + "or": [ + "amenity=bar", + "amenity=pub", + "amenity=cafe", + "amenity=biergarten" + ] + } + }, + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/cafe_pub/pub.svg", + "mappings": [ + { + "if": "amenity=cafe", + "then": "circle:white;./assets/layers/cafe_pub/cafe.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + } + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] + }, + "presets": [ + { + "tags": [ + "amenity=pub" + ], + "title": { + "en": "pub", + "nl": "bruin cafe of kroeg" + }, + "description": { + "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "tags": [ + "amenity=bar" + ], + "title": { + "en": "bar", + "nl": "bar" + }, + "description": { + "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "tags": [ + "amenity=cafe" + ], + "title": { + "en": "cafe", + "nl": "cafe" + }, + "description": { + "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." + }, + "preciseInput": { + "preferredBackground": "map" + } + } + ], + "title": { + "render": { + "nl": "Café" + }, + "mappings": [ + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}", + "en": "{name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "question": { + "nl": "Wat is de naam van dit café?", + "en": "What is the name of this pub?" + }, + "render": { + "nl": "De naam van dit café is {name}", + "en": "This pub is named {name}" + }, + "freeform": { + "key": "name" + }, + "id": "Name" + }, + { + "question": { + "en": "What kind of cafe is this", + "nl": "Welk soort café is dit?" + }, + "mappings": [ + { + "if": "amenity=pub", + "then": { + "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " + } + }, + { + "if": "amenity=bar", + "then": { + "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" + } + }, + { + "if": "amenity=cafe", + "then": { + "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." + } + }, + { + "if": "amenity=restaurant", + "then": { + "nl": "Dit is een restaurant waar men een maaltijd geserveerd krijgt" + } + }, + { + "if": "amenity=biergarten", + "then": { + "nl": "Een open ruimte waar bier geserveerd wordt. Typisch in Duitsland" + }, + "hideInAnswer": "_country!=de" + } + ], + "id": "Classification" + }, + "opening_hours", + "website", + "email", + "phone", + "payment-options", + "wheelchair-access", + "dog-access" + ], + "filter": [ + { + "id": "opened-now", + "options": [ + { + "question": { + "en": "Opened now", + "nl": "Nu geopened" + }, + "osmTags": "_isOpen=yes" + } + ] } - } ] - }, - "tagRenderings": [ - "images", - { - "#": "Name", - "question": { - "nl": "Wat is de naam van dit café?", - "en": "What is the name of this pub?" - }, - "render": { - "nl": "De naam van dit café is {name}", - "en": "This pub is named {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Classification", - "question": { - "en": "What kind of cafe is this", - "nl": "Welk soort café is dit?" - }, - "mappings": [ - { - "if": "amenity=pub", - "then": { - "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " - } - }, - { - "if": "amenity=bar", - "then": { - "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" - } - }, - { - "if": "amenity=cafe", - "then": { - "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." - } - }, - { - "if": "amenity=restaurant", - "then": { - "nl": "Dit is een restaurant waar men een maaltijd geserveerd krijgt" - } - }, - { - "if": "amenity=biergarten", - "then": { - "nl": "Een open ruimte waar bier geserveerd wordt. Typisch in Duitsland" - }, - "hideInAnswer": "_country!=de" - } - ] - }, - "opening_hours", - "website", - "email", - "phone", - "payment-options", - "wheelchair-access", - "dog-access" - ], - "filter": [ - { - "options": [ - { - "question": { - "en": "Opened now", - "nl": "Nu geopened" - }, - "osmTags": "_isOpen=yes" - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/charging_station/README.md b/assets/layers/charging_station/README.md new file mode 100644 index 000000000..445b81c1e --- /dev/null +++ b/assets/layers/charging_station/README.md @@ -0,0 +1,19 @@ +The charging station theme +========================== + +As you might have noticed, the charging station theme is complicated and large. + +There are a ton of repititive questions. Luckily, we can generate those. + +If you want to add a missing socket type, then: + +- Add all the properties in 'types.csv' +- Add an icon. (Note: icons are way better as pictures as they are perceived more abstractly) +- Update license_info.json with the copyright info of the new icon. Note that we strive to have Creative-commons icons only (though there are exceptions) + +AT this point, most of the work should be done; feel free to send a PR. If you would like to test it locally first (which is recommended) and have a working dev environment, then run: + +- Run 'ts-node csvToJson.ts' which will generate a new charging_station.json based on the protojson +- Run`npm run query:licenses` to get an interactive program to add the license of your artwork, followed by `npm run generate:licenses` +- Run `npm run generate:layeroverview` to generate the layer files +- Run `npm run start` to run the instance \ No newline at end of file diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 9c9aa4471..5a8385357 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -1,2183 +1,3233 @@ { - "id": "charging_station", - "name": { - "en": "Charging stations", - "it": "Stazioni di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjoner", - "ru": "Зарядные станции", - "zh_Hant": "充電站" - }, - "minzoom": 10, - "source": { - "osmTags": { - "or": [ - "amenity=charging_station", - "disused:amenity=charging_station", - "planned:amenity=charging_station", - "construction:amenity=charging_station" - ] - } - }, - "title": { - "render": { - "en": "Charging station", - "it": "Stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - } - }, - "description": { - "en": "A charging station", - "it": "Una stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "En ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - }, - "calculatedTags": [ - "motorcar=feat.properties.motorcar ?? feat.properties.car" - ], - "tagRenderings": [ - "images", - { - "#": "Type", - "question": { - "en": "Which vehicles are allowed to charge here?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "bicycle=yes", - "ifnot": "bicycle=no", - "then": { - "en": "bicycles can be charged here" - } - }, - { - "if": "motorcar=yes", - "extraTags": "car=", - "ifnot": { - "and": [ - "car=", - "motorcar=no" - ] - }, - "then": { - "en": "Cars can be charged here" - } - }, - { - "if": "scooter=yes", - "ifnot": "scooter=no", - "then": { - "en": "Scooters can be charged here" - } - }, - { - "if": "hgv=yes", - "ifnot": "hgv=no", - "then": { - "en": "Heavy good vehicles (such as trucks) can be charged here" - } - }, - { - "if": "bus=yes", - "ifnot": "bus=no", - "then": { - "en": "Buses can be charged here" - } - } - ] + "id": "charging_station", + "name": { + "en": "Charging stations", + "it": "Stazioni di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjoner", + "ru": "Зарядные станции", + "zh_Hant": "充電站" }, - { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}", - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform field used for access - doublecheck the value" - ] - }, - "mappings": [ - { - "if": "access=yes", - "then": "Anyone can use this charging station (payment might be needed)" - }, - { - "if": { + "minzoom": 10, + "source": { + "osmTags": { "or": [ - "access=permissive", - "access=public" + "amenity=charging_station", + "disused:amenity=charging_station", + "planned:amenity=charging_station", + "construction:amenity=charging_station" ] - }, - "then": "Anyone can use this charging station (payment might be needed)", - "hideInAnswer": true - }, - { - "if": "access=customers", - "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " - }, - { - "if": "access=private", - "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" } - ] }, - { - "#": "capacity", - "render": { - "en": "{capacity} vehicles can be charged here at the same time", - "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "question": { - "en": "How much vehicles can be charged here at the same time?", - "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" - }, - "freeform": { - "key": "capacity", - "type": "pnat" - } + "title": { + "render": { + "en": "Charging station", + "it": "Stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + } }, - { - "question": { - "en": "Which charging stations are available here?" - }, - "multiAnswer": true, - "mappings": [ + "description": { + "en": "A charging station", + "it": "Una stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "En ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + }, + "calculatedTags": [ + "motorcar=feat.properties.motorcar ?? feat.properties.car" + ], + "tagRenderings": [ + "images", { - "if": "socket:schuko=1", - "ifnot": "socket:schuko=", - "then": { - "en": "

Schuko wall plug without ground pin (CEE7/4 type F)

", - "nl": "

Schuko stekker zonder aardingspin (CEE7/4 type F)

" - } - }, - { - "if": { - "and": [ - "socket:schuko~*", - "socket:schuko!=1" + "id": "Type", + "question": { + "en": "Which vehicles are allowed to charge here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "bicycle=yes", + "ifnot": "bicycle=no", + "then": { + "en": "bicycles can be charged here" + } + }, + { + "if": "motorcar=yes", + "extraTags": "car=", + "ifnot": { + "and": [ + "car=", + "motorcar=no" + ] + }, + "then": { + "en": "Cars can be charged here" + } + }, + { + "if": "scooter=yes", + "ifnot": "scooter=no", + "then": { + "en": "Scooters can be charged here" + } + }, + { + "if": "hgv=yes", + "ifnot": "hgv=no", + "then": { + "en": "Heavy good vehicles (such as trucks) can be charged here" + } + }, + { + "if": "bus=yes", + "ifnot": "bus=no", + "then": { + "en": "Buses can be charged here" + } + } ] - }, - "then": { - "en": "

Schuko wall plug without ground pin (CEE7/4 type F)

", - "nl": "

Schuko stekker zonder aardingspin (CEE7/4 type F)

" - }, - "hideInAnswer": true }, { - "if": "socket:typee=1", - "ifnot": "socket:typee=", - "then": { - "en": "

European wall plug with ground pin (CEE7/4 type E)

", - "nl": "

Europese stekker met aardingspin (CEE7/4 type E)

" - } - }, - { - "if": { - "and": [ - "socket:typee~*", - "socket:typee!=1" + "id": "access", + "question": { + "en": "Who is allowed to use this charging station?" + }, + "render": { + "en": "Access is {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform field used for access - doublecheck the value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": "Anyone can use this charging station (payment might be needed)" + }, + { + "if": { + "or": [ + "access=permissive", + "access=public" + ] + }, + "then": "Anyone can use this charging station (payment might be needed)", + "hideInAnswer": true + }, + { + "if": "access=customers", + "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " + }, + { + "if": "access=private", + "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" + } ] - }, - "then": { - "en": "

European wall plug with ground pin (CEE7/4 type E)

", - "nl": "

Europese stekker met aardingspin (CEE7/4 type E)

" - }, - "hideInAnswer": true }, { - "if": "socket:chademo=1", - "ifnot": "socket:chademo=", - "then": { - "en": "

Chademo

", - "nl": "

" - } - }, - { - "if": { - "and": [ - "socket:chademo~*", - "socket:chademo!=1" - ] - }, - "then": { - "en": "

Chademo

", - "nl": "

" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_cable=1", - "ifnot": "socket:type1_cable=", - "then": { - "en": "

Type 1 with cable (J1772)

", - "nl": "

Type 1 met kabel (J1772)

" - } - }, - { - "if": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=1" - ] - }, - "then": { - "en": "

Type 1 with cable (J1772)

", - "nl": "

Type 1 met kabel (J1772)

" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1=1", - "ifnot": "socket:type1=", - "then": { - "en": "

Type 1 without cable (J1772)

", - "nl": "

Type 1 zonder kabel (J1772)

" - } - }, - { - "if": { - "and": [ - "socket:type1~*", - "socket:type1!=1" - ] - }, - "then": { - "en": "

Type 1 without cable (J1772)

", - "nl": "

Type 1 zonder kabel (J1772)

" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_combo=1", - "ifnot": "socket:type1_combo=", - "then": { - "en": "

Type 1 CCS (aka Type 1 Combo)

", - "nl": "

" - } - }, - { - "if": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=1" - ] - }, - "then": { - "en": "

Type 1 CCS (aka Type 1 Combo)

", - "nl": "

" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger=1", - "ifnot": "socket:tesla_supercharger=", - "then": { - "en": "

Tesla Supercharger

", - "nl": "

" - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=1" - ] - }, - "then": { - "en": "

Tesla Supercharger

", - "nl": "

" - }, - "hideInAnswer": true - }, - { - "if": "socket:type2=1", - "ifnot": "socket:type2=", - "then": { - "en": "

Type 2 (mennekes)

", - "nl": "

" - } - }, - { - "if": { - "and": [ - "socket:type2~*", - "socket:type2!=1" - ] - }, - "then": { - "en": "

Type 2 (mennekes)

", - "nl": "

" - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_combo=1", - "ifnot": "socket:type2_combo=", - "then": { - "en": "

Type 2 CCS (mennekes)

", - "nl": "

" - } - }, - { - "if": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=1" - ] - }, - "then": { - "en": "

Type 2 CCS (mennekes)

", - "nl": "

" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", - "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "freeform": { - "key": "socket:schuko", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "freeform": { - "key": "socket:schuko:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:voltage=230 V", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "freeform": { - "key": "socket:schuko:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:current=16 A", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "freeform": { - "key": "socket:schuko:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:output=3.6 kw", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", - "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "freeform": { - "key": "socket:typee", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "freeform": { - "key": "socket:typee:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:voltage=230 V", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "freeform": { - "key": "socket:typee:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:current=16 A", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "freeform": { - "key": "socket:typee:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:output=3 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - } - }, - { - "if": "socket:socket:typee:output=22 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Chademo are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Chademo plugs of type Chademo available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:chademo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Chademo offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Chademo outputs {socket:chademo:voltage} volt", - "nl": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "freeform": { - "key": "socket:chademo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:voltage=500 V", - "then": { - "en": "Chademo outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Chademo offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:current}A", - "nl": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "freeform": { - "key": "socket:chademo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:current=120 A", - "then": { - "en": "Chademo outputs at most 120 A", - "nl": " levert een stroom van maximaal 120 A" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Chademo offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:output}", - "nl": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "freeform": { - "key": "socket:chademo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:output=50 kw", - "then": { - "en": "Chademo outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 with cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", - "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "freeform": { - "key": "socket:type1_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " - }, - "render": { - "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type1_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:voltage=200 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 200 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1_cable:voltage=240 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 240 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "freeform": { - "key": "socket:type1_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:current=32 A", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 32 A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "freeform": { - "key": "socket:type1_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:output=3.7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1_cable:output=7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 without cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", - "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "freeform": { - "key": "socket:type1", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " - }, - "render": { - "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "freeform": { - "key": "socket:type1:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:voltage=200 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 200 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1:voltage=240 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 240 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "freeform": { - "key": "socket:type1:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:current=32 A", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 32 A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "freeform": { - "key": "socket:type1:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:output=3.7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1:output=6.6 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - } - }, - { - "if": "socket:socket:type1:output=7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - { - "if": "socket:socket:type1:output=7.2 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type1_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type1_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:voltage=400 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - }, - { - "if": "socket:socket:type1_combo:voltage=1000 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", - "nl": " heeft een spanning van 1000 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "freeform": { - "key": "socket:type1_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:current=50 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", - "nl": " levert een stroom van maximaal 50 A" - } - }, - { - "if": "socket:socket:type1_combo:current=125 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "freeform": { - "key": "socket:type1_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:output=50 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=62.5 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", - "nl": " levert een vermogen van maximaal 62.5 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=150 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=350 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", - "nl": " levert een vermogen van maximaal 350 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Tesla Supercharger are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_supercharger", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Tesla Supercharger offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:voltage=480 V", - "then": { - "en": "Tesla Supercharger outputs 480 volt", - "nl": " heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Tesla Supercharger offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:current=125 A", - "then": { - "en": "Tesla Supercharger outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger:current=350 A", - "then": { - "en": "Tesla Supercharger outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Tesla Supercharger offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:output=120 kw", - "then": { - "en": "Tesla Supercharger outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=150 kw", - "then": { - "en": "Tesla Supercharger outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=250 kw", - "then": { - "en": "Tesla Supercharger outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 2 (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", - "nl": " heeft een spanning van {socket:type2:voltage} volt" - }, - "freeform": { - "key": "socket:type2:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:voltage=230 V", - "then": { - "en": "Type 2 (mennekes) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2:voltage=400 V", - "then": { - "en": "Type 2 (mennekes) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", - "nl": " levert een stroom van maximaal {socket:type2:current}A" - }, - "freeform": { - "key": "socket:type2:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:current=16 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2:current=32 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 2 (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", - "nl": " levert een vermogen van maximaal {socket:type2:output}" - }, - "freeform": { - "key": "socket:type2:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:output=11 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2:output=22 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type2_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:voltage=500 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:type2_combo:voltage=920 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "freeform": { - "key": "socket:type2_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:current=125 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:type2_combo:current=350 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "freeform": { - "key": "socket:type2_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:output=50 kw", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "Authentication", - "question": { - "en": "What kind of authentication is available at the charging station?", - "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", - "ja": "この充電ステーションはいつオープンしますか?", - "nb_NO": "Når åpnet denne ladestasjonen?", - "ru": "В какое время работает эта зарядная станция?", - "zh_Hant": "何時是充電站開放使用的時間?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "authentication:membership_card=yes", - "ifnot": "authentication:membership_card=no", - "then": { - "en": "Authentication by a membership card" - } - }, - { - "if": "authentication:app=yes", - "ifnot": "authentication:app=no", - "then": { - "en": "Authentication by an app" - } - }, - { - "if": "authentication:phone_call=yes", - "ifnot": "authentication:phone_call=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:short_message=yes", - "ifnot": "authentication:short_message=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:nfc=yes", - "ifnot": "authentication:nfc=no", - "then": { - "en": "Authentication via NFC is available" - } - }, - { - "if": "authentication:money_card=yes", - "ifnot": "authentication:money_card=no", - "then": { - "en": "Authentication via Money Card is available" - } - }, - { - "if": "authentication:debit_card=yes", - "ifnot": "authentication:debit_card=no", - "then": { - "en": "Authentication via debit card is available" - } - }, - { - "if": "authentication:none=yes", - "ifnot": "authentication:none=no", - "then": { - "en": "No authentication is needed" - } - } - ] - }, - { - "#": "Auth phone", - "render": { - "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", - "it": "{network}", - "ja": "{network}", - "nb_NO": "{network}", - "ru": "{network}", - "zh_Hant": "{network}" - }, - "question": { - "en": "What's the phone number for authentication call or SMS?", - "it": "A quale rete appartiene questa stazione di ricarica?", - "ja": "この充電ステーションの運営チェーンはどこですか?", - "ru": "К какой сети относится эта станция?", - "zh_Hant": "充電站所屬的網路是?" - }, - "freeform": { - "key": "authentication:phone_call:number", - "type": "phone" - }, - "condition": { - "or": [ - "authentication:phone_call=yes", - "authentication:short_message=yes" - ] - }, - "it": { - "0": { - "then": "Non appartiene a una rete" - } - }, - "ja": { - "0": { - "then": "大規模な運営チェーンの一部ではない" - } - }, - "ru": { - "0": { - "then": "Не является частью более крупной сети" - } - }, - "zh_Hant": { - "0": { - "then": "不屬於大型網路" - } - } - }, - { - "#": "OH", - "render": "{opening_hours_table(opening_hours)}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "question": { - "en": "When is this charging station opened?" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "en": "24/7 opened (including holidays)" - } - } - ] - }, - { - "#": "fee/charge", - "question": { - "en": "How much does one have to pay to use this charging station?", - "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "render": { - "en": "Using this charging station costs {charge}", - "nl": "Dit oplaadpunt gebruiken kost {charge}" - }, - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "nl": "Gratis te gebruiken", - "en": "Free to use" - } - } - ] - }, - { - "builtin": "payment-options", - "override": { - "condition": { - "or": [ - "fee=yes", - "charge~*" - ] - }, - "mappings+": [ - { - "if": "payment:app=yes", - "ifnot": "payment:app=no", - "then": { - "en": "Payment is done using a dedicated app", - "nl": "Betalen via een app van het netwerk" + "id": "capacity", + "render": { + "en": "{capacity} vehicles can be charged here at the same time", + "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "question": { + "en": "How much vehicles can be charged here at the same time?", + "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" + }, + "freeform": { + "key": "capacity", + "type": "pnat" + } + }, + { + "id": "Available_charging_stations (generated)", + "question": { + "en": "Which charging stations are available here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "socket:schuko=1", + "ifnot": "socket:schuko=", + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F) Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F) European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E) European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E) Chademo
", + "nl": "
Chademo Chademo
", + "nl": "
Chademo Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772) Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772) Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772) Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772) Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo) Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo) Tesla Supercharger
", + "nl": "
Tesla Supercharger Tesla Supercharger
", + "nl": "
Tesla Supercharger Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes) Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes) Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes) Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes) Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772) Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772) Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo) Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo) Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination) Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination) Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te laden USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te ladenSchuko wall plug without ground pin (CEE7/4 type F) are available here?", + "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", + "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "freeform": { + "key": "socket:schuko", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "voltage-0", + "question": { + "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "freeform": { + "key": "socket:schuko:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:voltage=230 V", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "current-0", + "question": { + "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "freeform": { + "key": "socket:schuko:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:current=16 A", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "power-output-0", + "question": { + "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "freeform": { + "key": "socket:schuko:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:output=3.6 kw", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "plugs-1", + "question": { + "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", + "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "freeform": { + "key": "socket:typee", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "voltage-1", + "question": { + "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "freeform": { + "key": "socket:typee:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:voltage=230 V", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "current-1", + "question": { + "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "freeform": { + "key": "socket:typee:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:current=16 A", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "power-output-1", + "question": { + "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "freeform": { + "key": "socket:typee:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:output=3 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + } + }, + { + "if": "socket:socket:typee:output=22 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "plugs-2", + "question": { + "en": "How much plugs of type Chademo are available here?", + "nl": "Hoeveel stekkers van type Chademo heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Chademo plugs of type Chademo available here", + "nl": "Hier zijn Chademo stekkers van het type Chademo" + }, + "freeform": { + "key": "socket:chademo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "voltage-2", + "question": { + "en": "What voltage do the plugs with Chademo offer?", + "nl": "Welke spanning levert de stekker van type Chademo " + }, + "render": { + "en": "Chademo outputs {socket:chademo:voltage} volt", + "nl": "Chademo heeft een spanning van {socket:chademo:voltage} volt" + }, + "freeform": { + "key": "socket:chademo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:voltage=500 V", + "then": { + "en": "Chademo outputs 500 volt", + "nl": "Chademo heeft een spanning van 500 volt" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "current-2", + "question": { + "en": "What current do the plugs with Chademo offer?", + "nl": "Welke stroom levert de stekker van type Chademo ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:current}A", + "nl": "Chademo levert een stroom van maximaal {socket:chademo:current}A" + }, + "freeform": { + "key": "socket:chademo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:current=120 A", + "then": { + "en": "Chademo outputs at most 120 A", + "nl": "Chademo levert een stroom van maximaal 120 A" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "power-output-2", + "question": { + "en": "What power output does a single plug of type Chademo offer?", + "nl": "Welk vermogen levert een enkele stekker van type Chademo ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:output}", + "nl": "Chademo levert een vermogen van maximaal {socket:chademo:output}" + }, + "freeform": { + "key": "socket:chademo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:output=50 kw", + "then": { + "en": "Chademo outputs at most 50 kw", + "nl": "Chademo levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "plugs-3", + "question": { + "en": "How much plugs of type Type 1 with cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", + "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type1_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "voltage-3", + "question": { + "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " + }, + "render": { + "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type1_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:voltage=200 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 200 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1_cable:voltage=240 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 240 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "current-3", + "question": { + "en": "What current do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "freeform": { + "key": "socket:type1_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:current=32 A", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 32 A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "power-output-3", + "question": { + "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "freeform": { + "key": "socket:type1_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:output=3.7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1_cable:output=7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "plugs-4", + "question": { + "en": "How much plugs of type Type 1 without cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", + "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "freeform": { + "key": "socket:type1", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "voltage-4", + "question": { + "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " + }, + "render": { + "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "freeform": { + "key": "socket:type1:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:voltage=200 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 200 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1:voltage=240 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 240 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "current-4", + "question": { + "en": "What current do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "freeform": { + "key": "socket:type1:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:current=32 A", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 32 A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "power-output-4", + "question": { + "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "freeform": { + "key": "socket:type1:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:output=3.7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1:output=6.6 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + } + }, + { + "if": "socket:socket:type1:output=7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + { + "if": "socket:socket:type1:output=7.2 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "plugs-5", + "question": { + "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "nl": "Hoeveel stekkers van type Type 1 CCS (ook gekend als Type 1 Combo) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", + "nl": "Hier zijn Type 1 CCS (ook gekend als Type 1 Combo) stekkers van het type Type 1 CCS (ook gekend als Type 1 Combo)" + }, + "freeform": { + "key": "socket:type1_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "voltage-5", + "question": { + "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 CCS (ook gekend als Type 1 Combo) " + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type1_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:voltage=400 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van 400 volt" + } + }, + { + "if": "socket:socket:type1_combo:voltage=1000 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van 1000 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "current-5", + "question": { + "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 CCS (ook gekend als Type 1 Combo) ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "freeform": { + "key": "socket:type1_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:current=50 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal 50 A" + } + }, + { + "if": "socket:socket:type1_combo:current=125 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal 125 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "power-output-5", + "question": { + "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 CCS (ook gekend als Type 1 Combo) ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "freeform": { + "key": "socket:type1_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:output=50 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 50 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=62.5 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 62.5 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=150 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=350 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 350 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "plugs-6", + "question": { + "en": "How much plugs of type Tesla Supercharger are available here?", + "nl": "Hoeveel stekkers van type Tesla Supercharger heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", + "nl": "Hier zijn Tesla Supercharger stekkers van het type Tesla Supercharger" + }, + "freeform": { + "key": "socket:tesla_supercharger", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "voltage-6", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger offer?", + "nl": "Welke spanning levert de stekker van type Tesla Supercharger " + }, + "render": { + "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", + "nl": "Tesla Supercharger heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:voltage=480 V", + "then": { + "en": "Tesla Supercharger outputs 480 volt", + "nl": "Tesla Supercharger heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "current-6", + "question": { + "en": "What current do the plugs with Tesla Supercharger offer?", + "nl": "Welke stroom levert de stekker van type Tesla Supercharger ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", + "nl": "Tesla Supercharger levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:current=125 A", + "then": { + "en": "Tesla Supercharger outputs at most 125 A", + "nl": "Tesla Supercharger levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger:current=350 A", + "then": { + "en": "Tesla Supercharger outputs at most 350 A", + "nl": "Tesla Supercharger levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "power-output-6", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger offer?", + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", + "nl": "Tesla Supercharger levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:output=120 kw", + "then": { + "en": "Tesla Supercharger outputs at most 120 kw", + "nl": "Tesla Supercharger levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=150 kw", + "then": { + "en": "Tesla Supercharger outputs at most 150 kw", + "nl": "Tesla Supercharger levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=250 kw", + "then": { + "en": "Tesla Supercharger outputs at most 250 kw", + "nl": "Tesla Supercharger levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "plugs-7", + "question": { + "en": "How much plugs of type Type 2 (mennekes) are available here?", + "nl": "Hoeveel stekkers van type Type 2 (mennekes) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", + "nl": "Hier zijn Type 2 (mennekes) stekkers van het type Type 2 (mennekes)" + }, + "freeform": { + "key": "socket:type2", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "voltage-7", + "question": { + "en": "What voltage do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type Type 2 (mennekes) " + }, + "render": { + "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", + "nl": "Type 2 (mennekes) heeft een spanning van {socket:type2:voltage} volt" + }, + "freeform": { + "key": "socket:type2:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:voltage=230 V", + "then": { + "en": "Type 2 (mennekes) outputs 230 volt", + "nl": "Type 2 (mennekes) heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2:voltage=400 V", + "then": { + "en": "Type 2 (mennekes) outputs 400 volt", + "nl": "Type 2 (mennekes) heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "current-7", + "question": { + "en": "What current do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type Type 2 (mennekes) ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", + "nl": "Type 2 (mennekes) levert een stroom van maximaal {socket:type2:current}A" + }, + "freeform": { + "key": "socket:type2:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:current=16 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 16 A", + "nl": "Type 2 (mennekes) levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2:current=32 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 32 A", + "nl": "Type 2 (mennekes) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "power-output-7", + "question": { + "en": "What power output does a single plug of type Type 2 (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 2 (mennekes) ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", + "nl": "Type 2 (mennekes) levert een vermogen van maximaal {socket:type2:output}" + }, + "freeform": { + "key": "socket:type2:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:output=11 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 11 kw", + "nl": "Type 2 (mennekes) levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2:output=22 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 22 kw", + "nl": "Type 2 (mennekes) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "plugs-8", + "question": { + "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "nl": "Hoeveel stekkers van type Type 2 CCS (mennekes) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", + "nl": "Hier zijn Type 2 CCS (mennekes) stekkers van het type Type 2 CCS (mennekes)" + }, + "freeform": { + "key": "socket:type2_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "voltage-8", + "question": { + "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type Type 2 CCS (mennekes) " + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", + "nl": "Type 2 CCS (mennekes) heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type2_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:voltage=500 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 500 volt", + "nl": "Type 2 CCS (mennekes) heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:type2_combo:voltage=920 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 920 volt", + "nl": "Type 2 CCS (mennekes) heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "current-8", + "question": { + "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type Type 2 CCS (mennekes) ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "freeform": { + "key": "socket:type2_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:current=125 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 125 A", + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:type2_combo:current=350 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 350 A", + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "power-output-8", + "question": { + "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 2 CCS (mennekes) ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", + "nl": "Type 2 CCS (mennekes) levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "freeform": { + "key": "socket:type2_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:output=50 kw", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 50 kw", + "nl": "Type 2 CCS (mennekes) levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "plugs-9", + "question": { + "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here", + "nl": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type2_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "voltage-9", + "question": { + "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type2_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:voltage=230 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 230 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2_cable:voltage=400 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 400 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "current-9", + "question": { + "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "freeform": { + "key": "socket:type2_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:current=16 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 16 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2_cable:current=32 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 32 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "power-output-9", + "question": { + "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "freeform": { + "key": "socket:type2_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:output=11 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 11 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2_cable:output=22 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 22 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "plugs-10", + "question": { + "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "nl": "Hoeveel stekkers van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here", + "nl": "Hier zijn Tesla Supercharger CCS (een type2 CCS met Tesla-logo) stekkers van het type Tesla Supercharger CCS (een type2 CCS met Tesla-logo)" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "voltage-10", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke spanning levert de stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) " + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "current-10", + "question": { + "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke stroom levert de stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:current=125 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:current=350 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "power-output-10", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw", + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "plugs-11", + "question": { + "en": "How much plugs of type Tesla Supercharger (destination) are available here?", + "nl": "Hoeveel stekkers van type Tesla Supercharger (destination) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", + "nl": "Hier zijn Tesla Supercharger (destination) stekkers van het type Tesla Supercharger (destination)" + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-11", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke spanning levert de stekker van type Tesla Supercharger (destination) " + }, + "render": { + "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", + "nl": "Tesla Supercharger (destination) heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=480 V", + "then": { + "en": "Tesla Supercharger (destination) outputs 480 volt", + "nl": "Tesla Supercharger (destination) heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-11", + "question": { + "en": "What current do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke stroom levert de stekker van type Tesla Supercharger (destination) ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=125 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 125 A", + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=350 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 350 A", + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-11", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger (destination) ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}", + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=120 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 120 kw", + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=150 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 150 kw", + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=250 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 250 kw", + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "plugs-12", + "question": { + "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "nl": "Hoeveel stekkers van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here", + "nl": "Hier zijn Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) stekkers van het type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)" + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-12", + "question": { + "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke spanning levert de stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) " + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=230 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:tesla_destination:voltage=400 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-12", + "question": { + "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke stroom levert de stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=16 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=32 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-12", + "question": { + "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=11 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=22 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw", + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "plugs-13", + "question": { + "en": "How much plugs of type USB to charge phones and small electronics are available here?", + "nl": "Hoeveel stekkers van type USB om GSMs en kleine electronica op te laden heeft dit oplaadpunt?" + }, + "render": { + "en": "There are USB to charge phones and small electronics plugs of type USB to charge phones and small electronics available here", + "nl": "Hier zijn USB om GSMs en kleine electronica op te laden stekkers van het type USB om GSMs en kleine electronica op te laden" + }, + "freeform": { + "key": "socket:USB-A", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "voltage-13", + "question": { + "en": "What voltage do the plugs with USB to charge phones and small electronics offer?", + "nl": "Welke spanning levert de stekker van type USB om GSMs en kleine electronica op te laden " + }, + "render": { + "en": "USB to charge phones and small electronics outputs {socket:USB-A:voltage} volt", + "nl": "USB om GSMs en kleine electronica op te laden heeft een spanning van {socket:USB-A:voltage} volt" + }, + "freeform": { + "key": "socket:USB-A:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:voltage=5 V", + "then": { + "en": "USB to charge phones and small electronics outputs 5 volt", + "nl": "USB om GSMs en kleine electronica op te laden heeft een spanning van 5 volt" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "current-13", + "question": { + "en": "What current do the plugs with USB to charge phones and small electronics offer?", + "nl": "Welke stroom levert de stekker van type USB om GSMs en kleine electronica op te laden ?" + }, + "render": { + "en": "USB to charge phones and small electronics outputs at most {socket:USB-A:current}A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal {socket:USB-A:current}A" + }, + "freeform": { + "key": "socket:USB-A:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:current=1 A", + "then": { + "en": "USB to charge phones and small electronics outputs at most 1 A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal 1 A" + } + }, + { + "if": "socket:socket:USB-A:current=2 A", + "then": { + "en": "USB to charge phones and small electronics outputs at most 2 A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal 2 A" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "power-output-13", + "question": { + "en": "What power output does a single plug of type USB to charge phones and small electronics offer?", + "nl": "Welk vermogen levert een enkele stekker van type USB om GSMs en kleine electronica op te laden ?" + }, + "render": { + "en": "USB to charge phones and small electronics outputs at most {socket:USB-A:output}", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal {socket:USB-A:output}" + }, + "freeform": { + "key": "socket:USB-A:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:output=5w", + "then": { + "en": "USB to charge phones and small electronics outputs at most 5w", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal 5w" + } + }, + { + "if": "socket:socket:USB-A:output=10w", + "then": { + "en": "USB to charge phones and small electronics outputs at most 10w", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal 10w" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "Authentication", + "question": { + "en": "What kind of authentication is available at the charging station?", + "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", + "ja": "この充電ステーションはいつオープンしますか?", + "nb_NO": "Når åpnet denne ladestasjonen?", + "ru": "В какое время работает эта зарядная станция?", + "zh_Hant": "何時是充電站開放使用的時間?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "authentication:membership_card=yes", + "ifnot": "authentication:membership_card=no", + "then": { + "en": "Authentication by a membership card" + } + }, + { + "if": "authentication:app=yes", + "ifnot": "authentication:app=no", + "then": { + "en": "Authentication by an app" + } + }, + { + "if": "authentication:phone_call=yes", + "ifnot": "authentication:phone_call=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:short_message=yes", + "ifnot": "authentication:short_message=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:nfc=yes", + "ifnot": "authentication:nfc=no", + "then": { + "en": "Authentication via NFC is available" + } + }, + { + "if": "authentication:money_card=yes", + "ifnot": "authentication:money_card=no", + "then": { + "en": "Authentication via Money Card is available" + } + }, + { + "if": "authentication:debit_card=yes", + "ifnot": "authentication:debit_card=no", + "then": { + "en": "Authentication via debit card is available" + } + }, + { + "if": "authentication:none=yes", + "ifnot": "authentication:none=no", + "then": { + "en": "No authentication is needed" + } + } + ] + }, + { + "id": "Auth phone", + "render": { + "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", + "it": "{network}", + "ja": "{network}", + "nb_NO": "{network}", + "ru": "{network}", + "zh_Hant": "{network}" + }, + "question": { + "en": "What's the phone number for authentication call or SMS?", + "it": "A quale rete appartiene questa stazione di ricarica?", + "ja": "この充電ステーションの運営チェーンはどこですか?", + "ru": "К какой сети относится эта станция?", + "zh_Hant": "充電站所屬的網路是?" + }, + "freeform": { + "key": "authentication:phone_call:number", + "type": "phone" + }, + "condition": { + "or": [ + "authentication:phone_call=yes", + "authentication:short_message=yes" + ] + }, + "it": { + "0": { + "then": "Non appartiene a una rete" + } + }, + "ja": { + "0": { + "then": "大規模な運営チェーンの一部ではない" + } + }, + "ru": { + "0": { + "then": "Не является частью более крупной сети" + } + }, + "zh_Hant": { + "0": { + "then": "不屬於大型網路" + } + } + }, + { + "id": "OH", + "render": "{opening_hours_table(opening_hours)}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "question": { + "en": "When is this charging station opened?" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "en": "24/7 opened (including holidays)" + } + } + ] + }, + { + "id": "fee/charge", + "question": { + "en": "How much does one have to pay to use this charging station?", + "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "render": { + "en": "Using this charging station costs {charge}", + "nl": "Dit oplaadpunt gebruiken kost {charge}" + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "nl": "Gratis te gebruiken", + "en": "Free to use" + } + } + ] + }, + { + "id": "payment-options", + "builtin": "payment-options", + "override": { + "condition": { + "or": [ + "fee=yes", + "charge~*" + ] + }, + "mappings+": [ + { + "if": "payment:app=yes", + "ifnot": "payment:app=no", + "then": { + "en": "Payment is done using a dedicated app", + "nl": "Betalen via een app van het netwerk" + } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } + } + ] + } + }, + { + "id": "maxstay", + "question": { + "en": "What is the maximum amount of time one is allowed to stay here?", + "nl": "Hoelang mag een voertuig hier blijven staan?" + }, + "freeform": { + "key": "maxstay" + }, + "render": { + "en": "One can stay at most {canonical(maxstay)}", + "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "mappings": [ + { + "if": "maxstay=unlimited", + "then": { + "en": "No timelimit on leaving your vehicle here", + "nl": "Geen maximum parkeertijd" + } + } + ] + }, + { + "id": "Network", + "render": { + "en": "Part of the network {network}" + }, + "question": { + "en": "Is this charging station part of a network?" + }, + "freeform": { + "key": "network" + }, + "mappings": [ + { + "if": "no:network=yes", + "then": { + "en": "Not part of a bigger network" + } + }, + { + "if": "network=none", + "then": { + "en": "Not part of a bigger network" + }, + "hideInAnswer": true + }, + { + "if": "network=AeroVironment", + "then": "AeroVironment" + }, + { + "if": "network=Blink", + "then": "Blink" + }, + { + "if": "network=eVgo", + "then": "eVgo" + } + ] + }, + { + "id": "Operator", + "question": { + "en": "Who is the operator of this charging station?" + }, + "render": { + "en": "This charging station is operated by {operator}" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "network:={operator}" + ] + }, + "then": { + "en": "Actually, {operator} is the network" + }, + "addExtraTags": [ + "operator=" + ], + "hideInAnswer": "operator=" + } + ] + }, + { + "id": "phone", + "question": { + "en": "What number can one call if there is a problem with this charging station?" + }, + "render": { + "en": "In case of problems, call {phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "id": "email", + "question": { + "en": "What is the email address of the operator?" + }, + "render": { + "en": "In case of problems, send an email to {email}" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "id": "website", + "question": { + "en": "What is the website of the operator?" + }, + "render": { + "en": "More info on {website}" + }, + "freeform": { + "key": "website", + "type": "url" + } + }, + "level", + { + "id": "ref", + "question": { + "en": "What is the reference number of this charging station?" + }, + "render": { + "en": "Reference number is {ref}" + }, + "freeform": { + "key": "ref" + } + }, + { + "id": "Operational status", + "question": { + "en": "Is this charging point in use?", + "nl": "Is dit oplaadpunt operationeel?" + }, + "mappings": [ + { + "if": "operational_status=broken", + "then": { + "en": "This charging station is broken", + "nl": "Dit oplaadpunt is kapot" + } + }, + { + "if": { + "and": [ + "planned:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is planned here", + "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" + } + }, + { + "if": { + "and": [ + "construction:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is constructed here", + "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" + } + }, + { + "if": { + "and": [ + "disused:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", + "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" + } + }, + { + "if": { + "and": [ + "amenity=charging_station", + "operational_status=" + ] + }, + "then": { + "en": "This charging station works", + "nl": "Dit oplaadpunt werkt" + } + } + ] + }, + { + "id": "Parking:fee", + "question": { + "en": "Does one have to pay a parking fee while charging?" + }, + "mappings": [ + { + "if": "parking:fee=no", + "then": { + "en": "No additional parking cost while charging" + } + }, + { + "if": "parking:fee=yes", + "then": { + "en": "An additional parking fee should be paid while charging" + } + } + ] + } + ], + "icon": { + "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", + "mappings": [ + { + "if": "bicycle=yes", + "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" + }, + { + "if": { + "or": [ + "car=yes", + "motorcar=yes" + ] + }, + "then": "pin:#fff;./assets/themes/charging_stations/car.svg" } - } ] - } }, - { - "#": "maxstay", - "question": { - "en": "What is the maximum amount of time one is allowed to stay here?", - "nl": "Hoelang mag een voertuig hier blijven staan?" - }, - "freeform": { - "key": "maxstay" - }, - "render": { - "en": "One can stay at most {canonical(maxstay)}", - "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "mappings": [ + "iconOverlays": [ { - "if": "maxstay=unlimited", - "then": { - "en": "No timelimit on leaving your vehicle here", - "nl": "Geen maximum parkeertijd" - } + "if": { + "or": [ + "disused:amenity=charging_station", + "operational_status=broken" + ] + }, + "then": "cross_bottom_right:#c22;" + }, + { + "if": { + "or": [ + "proposed:amenity=charging_station", + "planned:amenity=charging_station" + ] + }, + "then": "./assets/layers/charging_station/under_construction.svg", + "badge": true + }, + { + "if": { + "and": [ + "bicycle=yes", + { + "or": [ + "motorcar=yes", + "car=yes" + ] + } + ] + }, + "then": "circle:#fff;./assets/themes/charging_stations/car.svg", + "badge": true } - ] + ], + "width": { + "render": "8" }, - { - "#": "Network", - "render": { - "en": "Part of the network {network}" - }, - "question": { - "en": "Is this charging station part of a network?" - }, - "freeform": { - "key": "network" - }, - "mappings": [ + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#00f" + }, + "presets": [ { - "if": "no:network=yes", - "then": { - "en": "Not part of a bigger network" - } - }, - { - "if": "network=none", - "then": { - "en": "Not part of a bigger network" - }, - "hideInAnswer": true - }, - { - "if": "network=AeroVironment", - "then": "AeroVironment" - }, - { - "if": "network=Blink", - "then": "Blink" - }, - { - "if": "network=eVgo", - "then": "eVgo" + "tags": [ + "amenity=charging_station" + ], + "title": { + "en": "Charging station" + }, + "preciseInput": { + "preferredBackground": "map" + } } - ] - }, - { - "#": "Operator", - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}", - "freeform": { - "key": "operator" - }, - "mappings": [ + ], + "wayHandling": 1, + "filter": [ { - "if": { - "and": [ - "network:={operator}" + "id": "vehicle-type", + "options": [ + { + "question": { + "en": "All vehicle types", + "nl": "Alle voertuigen" + } + }, + { + "question": { + "en": "Charging station for bicycles", + "nl": "Oplaadpunten voor fietsen" + }, + "osmTags": "bicycle=yes" + }, + { + "question": { + "en": "Charging station for cars", + "nl": "Oplaadpunten voor auto's" + }, + "osmTags": { + "or": [ + "car=yes", + "motorcar=yes" + ] + } + } + ] + }, + { + "id": "working", + "options": [ + { + "question": { + "en": "Only working charging stations" + }, + "osmTags": { + "and": [ + "operational_status!=broken", + "amenity=charging_station" + ] + } + } + ] + }, + { + "id": "connection_type", + "options": [ + { + "question": { + "en": "All connectors", + "nl": "Alle types" + } + }, + { + "question": { + "en": "Has a Schuko wall plug without ground pin (CEE7/4 type F) connector", + "nl": "Heeft een Schuko stekker zonder aardingspin (CEE7/4 type F) " + }, + "osmTags": "socket:schuko~*" + }, + { + "question": { + "en": "Has a European wall plug with ground pin (CEE7/4 type E) connector", + "nl": "Heeft een Europese stekker met aardingspin (CEE7/4 type E) " + }, + "osmTags": "socket:typee~*" + }, + { + "question": { + "en": "Has a Chademo connector", + "nl": "Heeft een Chademo " + }, + "osmTags": "socket:chademo~*" + }, + { + "question": { + "en": "Has a Type 1 with cable (J1772) connector", + "nl": "Heeft een Type 1 met kabel (J1772) " + }, + "osmTags": "socket:type1_cable~*" + }, + { + "question": { + "en": "Has a Type 1 without cable (J1772) connector", + "nl": "Heeft een Type 1 zonder kabel (J1772) " + }, + "osmTags": "socket:type1~*" + }, + { + "question": { + "en": "Has a Type 1 CCS (aka Type 1 Combo) connector", + "nl": "Heeft een Type 1 CCS (ook gekend als Type 1 Combo) " + }, + "osmTags": "socket:type1_combo~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger connector", + "nl": "Heeft een Tesla Supercharger " + }, + "osmTags": "socket:tesla_supercharger~*" + }, + { + "question": { + "en": "Has a Type 2 (mennekes) connector", + "nl": "Heeft een Type 2 (mennekes) " + }, + "osmTags": "socket:type2~*" + }, + { + "question": { + "en": "Has a Type 2 CCS (mennekes) connector", + "nl": "Heeft een Type 2 CCS (mennekes) " + }, + "osmTags": "socket:type2_combo~*" + }, + { + "question": { + "en": "Has a Type 2 with cable (mennekes) connector", + "nl": "Heeft een Type 2 met kabel (J1772) " + }, + "osmTags": "socket:type2_cable~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger CCS (a branded type2_css) connector", + "nl": "Heeft een Tesla Supercharger CCS (een type2 CCS met Tesla-logo) " + }, + "osmTags": "socket:tesla_supercharger_ccs~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger (destination) connector", + "nl": "Heeft een Tesla Supercharger (destination) " + }, + "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a Tesla supercharger (destination (A Type 2 with cable branded as tesla) connector", + "nl": "Heeft een Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) " + }, + "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a USB to charge phones and small electronics connector", + "nl": "Heeft een USB om GSMs en kleine electronica op te laden " + }, + "osmTags": "socket:USB-A~*" + } ] - }, - "then": "Actually, {operator} is the network", - "addExtraTags": [ - "operator=" - ], - "hideInAnswer": "operator=" } - ] - }, - { - "#": "phone", - "question": { - "en": "What number can one call if there is a problem with this charging station?" - }, - "render": { - "en": "In case of problems, call {phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "#": "email", - "question": { - "en": "What is the email address of the operator?" - }, - "render": { - "en": "In case of problems, send an email to {email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "#": "website", - "question": { - "en": "What is the website of the operator?" - }, - "render": { - "en": "More info on {website}" - }, - "freeform": { - "key": "website", - "type": "url" - } - }, - "level", - { - "#": "ref", - "question": { - "en": "What is the reference number of this charging station?" - }, - "render": "Reference number is {ref}", - "freeform": { - "key": "ref" - } - }, - { - "#": "Operational status", - "question": { - "en": "Is this charging point in use?", - "nl": "Is dit oplaadpunt operationeel?" - }, - "mappings": [ + ], + "units": [ { - "if": "operational_status=broken", - "then": { - "en": "This charging station is broken", - "nl": "Dit oplaadpunt is kapot" - } - }, - { - "if": { - "and": [ - "planned:amenity=charging_station", - "amenity=" + "appliesToKey": [ + "maxstay" + ], + "applicableUnits": [ + { + "canonicalDenomination": "minutes", + "canonicalDenominationSingular": "minute", + "alternativeDenomination": [ + "m", + "min", + "mins", + "minuten", + "mns" + ], + "human": { + "en": " minutes", + "nl": " minuten" + }, + "humanSingular": { + "en": " minute", + "nl": " minuut" + } + }, + { + "canonicalDenomination": "hours", + "canonicalDenominationSingular": "hour", + "alternativeDenomination": [ + "h", + "hrs", + "hours", + "u", + "uur", + "uren" + ], + "human": { + "en": " hours", + "nl": " uren" + }, + "humanSingular": { + "en": " hour", + "nl": " uur" + } + }, + { + "canonicalDenomination": "days", + "canonicalDenominationSingular": "day", + "alternativeDenomination": [ + "dys", + "dagen", + "dag" + ], + "human": { + "en": " days", + "nl": " day" + }, + "humanSingular": { + "en": " day", + "nl": " dag" + } + } ] - }, - "then": { - "en": "A charging station is planned here", - "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" - } }, { - "if": { - "and": [ - "construction:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "A charging station is constructed here", - "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" - } + "appliesToKey": [ + "socket:schuko:voltage", + "socket:typee:voltage", + "socket:chademo:voltage", + "socket:type1_cable:voltage", + "socket:type1:voltage", + "socket:type1_combo:voltage", + "socket:tesla_supercharger:voltage", + "socket:type2:voltage", + "socket:type2_combo:voltage", + "socket:type2_cable:voltage", + "socket:tesla_supercharger_ccs:voltage", + "socket:tesla_destination:voltage", + "socket:tesla_destination:voltage", + "socket:USB-A:voltage" + ], + "applicableUnits": [ + { + "canonicalDenomination": "V", + "alternativeDenomination": [ + "v", + "volt", + "voltage", + "V", + "Volt" + ], + "human": { + "en": "Volts", + "nl": "volt" + } + } + ], + "eraseInvalidValues": true }, { - "if": { - "and": [ - "disused:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", - "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" - } + "appliesToKey": [ + "socket:schuko:current", + "socket:typee:current", + "socket:chademo:current", + "socket:type1_cable:current", + "socket:type1:current", + "socket:type1_combo:current", + "socket:tesla_supercharger:current", + "socket:type2:current", + "socket:type2_combo:current", + "socket:type2_cable:current", + "socket:tesla_supercharger_ccs:current", + "socket:tesla_destination:current", + "socket:tesla_destination:current", + "socket:USB-A:current" + ], + "applicableUnits": [ + { + "canonicalDenomination": "A", + "alternativeDenomination": [ + "a", + "amp", + "amperage", + "A" + ], + "human": { + "en": "A", + "nl": "A" + } + } + ], + "eraseInvalidValues": true }, { - "if": "amenity=charging_station", - "then": { - "en": "This charging station works", - "nl": "Dit oplaadpunt werkt" - } + "appliesToKey": [ + "socket:schuko:output", + "socket:typee:output", + "socket:chademo:output", + "socket:type1_cable:output", + "socket:type1:output", + "socket:type1_combo:output", + "socket:tesla_supercharger:output", + "socket:type2:output", + "socket:type2_combo:output", + "socket:type2_cable:output", + "socket:tesla_supercharger_ccs:output", + "socket:tesla_destination:output", + "socket:tesla_destination:output", + "socket:USB-A:output" + ], + "applicableUnits": [ + { + "canonicalDenomination": "kW", + "alternativeDenomination": [ + "kilowatt" + ], + "human": { + "en": "kilowatt", + "nl": "kilowatt" + } + }, + { + "canonicalDenomination": "mW", + "alternativeDenomination": [ + "megawatt" + ], + "human": { + "en": "megawatt", + "nl": "megawatt" + } + } + ], + "eraseInvalidValues": true } - ] - } - ], - "icon": { - "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", - "mappings": [ - { - "if": "bicycle=yes", - "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" - }, - { - "if": { - "or": [ - "car=yes", - "motorcar=yes" - ] - }, - "then": "pin:#fff;./assets/themes/charging_stations/car.svg" - } ] - }, - "iconOverlays": [ - { - "if": { - "or": [ - "disused:amenity=charging_station", - "operational_status=broken" - ] - }, - "then": "cross_bottom_right:#c22;" - }, - { - "if": { - "or": [ - "proposed:amenity=charging_station", - "planned:amenity=charging_station" - ] - }, - "then": "./assets/layers/charging_station/under_construction.svg", - "badge": true - }, - { - "if": { - "and": [ - "bicycle=yes", - { - "or": [ - "motorcar=yes", - "car=yes" - ] - } - ] - }, - "then": "circle:#fff;./assets/themes/charging_stations/car.svg", - "badge": true - } - ], - "width": { - "render": "8" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=charging_station" - ], - "title": { - "en": "Charging station" - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "wayHandling": 1, - "filter": [ - { - "options": [ - { - "question": { - "en": "All vehicle types", - "nl": "Alle voertuigen" - } - }, - { - "question": { - "en": "Charging station for bicycles", - "nl": "Oplaadpunten voor fietsen" - }, - "osmTags": "bicycle=yes" - }, - { - "question": { - "en": "Charging station for cars", - "nl": "Oplaadpunten voor auto's" - }, - "osmTags": { - "or": [ - "car=yes", - "motorcar=yes" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "en": "Only working charging stations" - }, - "osmTags": { - "and": [ - "operational_status!=broken", - "amenity=charging_station" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "en": "All connectors", - "nl": "Alle types" - } - }, - { - "question": { - "en": "Has a Schuko wall plug without ground pin (CEE7/4 type F) connector", - "nl": "Heeft een Schuko stekker zonder aardingspin (CEE7/4 type F) " - }, - "osmTags": "socket:schuko~*" - }, - { - "question": { - "en": "Has a European wall plug with ground pin (CEE7/4 type E) connector", - "nl": "Heeft een Europese stekker met aardingspin (CEE7/4 type E) " - }, - "osmTags": "socket:typee~*" - }, - { - "question": { - "en": "Has a Chademo connector", - "nl": "Heeft een " - }, - "osmTags": "socket:chademo~*" - }, - { - "question": { - "en": "Has a Type 1 with cable (J1772) connector", - "nl": "Heeft een Type 1 met kabel (J1772) " - }, - "osmTags": "socket:type1_cable~*" - }, - { - "question": { - "en": "Has a Type 1 without cable (J1772) connector", - "nl": "Heeft een Type 1 zonder kabel (J1772) " - }, - "osmTags": "socket:type1~*" - }, - { - "question": { - "en": "Has a Type 1 CCS (aka Type 1 Combo) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type1_combo~*" - }, - { - "question": { - "en": "Has a Tesla Supercharger connector", - "nl": "Heeft een " - }, - "osmTags": "socket:tesla_supercharger~*" - }, - { - "question": { - "en": "Has a Type 2 (mennekes) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type2~*" - }, - { - "question": { - "en": "Has a Type 2 CCS (mennekes) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type2_combo~*" - } - ] - } - ], - "units": [ - { - "appliesToKey": [ - "maxstay" - ], - "applicableUnits": [ - { - "canonicalDenomination": "minutes", - "canonicalDenominationSingular": "minute", - "alternativeDenomination": [ - "m", - "min", - "mins", - "minuten", - "mns" - ], - "human": { - "en": " minutes", - "nl": " minuten" - }, - "humanSingular": { - "en": " minute", - "nl": " minuut" - } - }, - { - "canonicalDenomination": "hours", - "canonicalDenominationSingular": "hour", - "alternativeDenomination": [ - "h", - "hrs", - "hours", - "u", - "uur", - "uren" - ], - "human": { - "en": " hours", - "nl": " uren" - }, - "humanSingular": { - "en": " hour", - "nl": " uur" - } - }, - { - "canonicalDenomination": "days", - "canonicalDenominationSingular": "day", - "alternativeDenomination": [ - "dys", - "dagen", - "dag" - ], - "human": { - "en": " days", - "nl": " day" - }, - "humanSingular": { - "en": " day", - "nl": " dag" - } - } - ] - }, - { - "appliesToKey": [ - "socket:schuko:voltage", - "socket:typee:voltage", - "socket:chademo:voltage", - "socket:type1_cable:voltage", - "socket:type1:voltage", - "socket:type1_combo:voltage", - "socket:tesla_supercharger:voltage", - "socket:type2:voltage", - "socket:type2_combo:voltage" - ], - "applicableUnits": [ - { - "canonicalDenomination": "V", - "alternativeDenomination": [ - "v", - "volt", - "voltage", - "V", - "Volt" - ], - "human": { - "en": "Volts", - "nl": "volt" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:current", - "socket:typee:current", - "socket:chademo:current", - "socket:type1_cable:current", - "socket:type1:current", - "socket:type1_combo:current", - "socket:tesla_supercharger:current", - "socket:type2:current", - "socket:type2_combo:current" - ], - "applicableUnits": [ - { - "canonicalDenomination": "A", - "alternativeDenomination": [ - "a", - "amp", - "amperage", - "A" - ], - "human": { - "en": "A", - "nl": "A" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:output", - "socket:typee:output", - "socket:chademo:output", - "socket:type1_cable:output", - "socket:type1:output", - "socket:type1_combo:output", - "socket:tesla_supercharger:output", - "socket:type2:output", - "socket:type2_combo:output" - ], - "applicableUnits": [ - { - "canonicalDenomination": "kW", - "alternativeDenomination": [ - "kilowatt" - ], - "human": { - "en": "kilowatt", - "nl": "kilowatt" - } - }, - { - "canonicalDenomination": "mW", - "alternativeDenomination": [ - "megawatt" - ], - "human": { - "en": "megawatt", - "nl": "megawatt" - } - } - ], - "eraseInvalidValues": true - } - ] } \ No newline at end of file diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index ddc91b36a..73aced6ad 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -43,7 +43,7 @@ "tagRenderings": [ "images", { - "#": "Type", + "id": "Type", "question": { "en": "Which vehicles are allowed to charge here?" }, @@ -93,8 +93,13 @@ ] }, { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}", + "id": "access", + "question": { + "en": "Who is allowed to use this charging station?" + }, + "render": { + "en": "Access is {access}" + }, "freeform": { "key": "access", "addExtraTags": [ @@ -127,7 +132,7 @@ ] }, { - "#": "capacity", + "id": "capacity", "render": { "en": "{capacity} vehicles can be charged here at the same time", "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" @@ -141,9 +146,9 @@ "type": "pnat" } }, - $$$ + {"id": "$$$"}, { - "#": "Authentication", + "id": "Authentication", "question": { "en": "What kind of authentication is available at the charging station?", "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", @@ -213,7 +218,7 @@ ] }, { - "#": "Auth phone", + "id": "Auth phone", "render": { "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", "it": "{network}", @@ -261,7 +266,7 @@ } }, { - "#": "OH", + "id": "OH", "render": "{opening_hours_table(opening_hours)}", "freeform": { "key": "opening_hours", @@ -280,7 +285,7 @@ ] }, { - "#": "fee/charge", + "id": "fee/charge", "question": { "en": "How much does one have to pay to use this charging station?", "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" @@ -311,6 +316,7 @@ ] }, { + "id": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -327,12 +333,20 @@ "en": "Payment is done using a dedicated app", "nl": "Betalen via een app van het netwerk" } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } } ] } }, { - "#": "maxstay", + "id": "maxstay", "question": { "en": "What is the maximum amount of time one is allowed to stay here?", "nl": "Hoelang mag een voertuig hier blijven staan?" @@ -355,7 +369,7 @@ ] }, { - "#": "Network", + "id": "Network", "render": { "en": "Part of the network {network}" }, @@ -394,9 +408,13 @@ ] }, { - "#": "Operator", - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}", + "id": "Operator", + "question": { + "en": "Who is the operator of this charging station?" + }, + "render": { + "en": "This charging station is operated by {operator}" + }, "freeform": { "key": "operator" }, @@ -407,7 +425,9 @@ "network:={operator}" ] }, - "then": "Actually, {operator} is the network", + "then": { + "en": "Actually, {operator} is the network" + }, "addExtraTags": [ "operator=" ], @@ -416,7 +436,7 @@ ] }, { - "#": "phone", + "id": "phone", "question": { "en": "What number can one call if there is a problem with this charging station?" }, @@ -429,7 +449,7 @@ } }, { - "#": "email", + "id": "email", "question": { "en": "What is the email address of the operator?" }, @@ -442,7 +462,7 @@ } }, { - "#": "website", + "id": "website", "question": { "en": "What is the website of the operator?" }, @@ -456,17 +476,19 @@ }, "level", { - "#": "ref", + "id": "ref", "question": { "en": "What is the reference number of this charging station?" }, - "render": "Reference number is {ref}", + "render": { + "en": "Reference number is {ref}" + }, "freeform": { "key": "ref" } }, { - "#": "Operational status", + "id": "Operational status", "question": { "en": "Is this charging point in use?", "nl": "Is dit oplaadpunt operationeel?" @@ -516,13 +538,35 @@ } }, { - "if": "amenity=charging_station", + "if": { + "and": ["amenity=charging_station","operational_status="] + }, "then": { "en": "This charging station works", "nl": "Dit oplaadpunt werkt" } } ] + }, + { + "id": "Parking:fee", + "question": { + "en": "Does one have to pay a parking fee while charging?" + }, + "mappings": [ + { + "if": "parking:fee=no", + "then": { + "en": "No additional parking cost while charging" + } + }, + { + "if": "parking:fee=yes", + "then": { + "en": "An additional parking fee should be paid while charging" + } + } + ] } ], "icon": { @@ -604,6 +648,7 @@ "wayHandling": 1, "filter": [ { + "id": "vehicle-type", "options": [ { "question": { @@ -633,6 +678,7 @@ ] }, { + "id": "working", "options": [ { "question": { diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index 80c3e557e..2bd8d787a 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -2,6 +2,7 @@ import {readFileSync, writeFileSync} from "fs"; import {Utils} from "../../../Utils"; import {TagRenderingConfigJson} from "../../../Models/ThemeConfig/Json/TagRenderingConfigJson"; import ScriptUtils from "../../../scripts/ScriptUtils"; +import {LayerConfigJson} from "../../../Models/ThemeConfig/Json/LayerConfigJson"; function colonSplit(value: string): string[] { @@ -13,9 +14,11 @@ function loadCsv(file): { image: string, description: Map, countryWhiteList?: string[], + countryBlackList?: string[], commonVoltages?: number[], commonCurrents?: number[], - commonOutputs?: string[] + commonOutputs?: string[], + associatedVehicleTypes?:string[] }[] { const entries: string[] = Utils.NoNull(readFileSync(file, "utf8").split("\n").map(str => str.trim())) const header = entries.shift().split(",") @@ -27,7 +30,7 @@ function loadCsv(file): { } const v = {} - const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList"] + const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList","countryBlackList","associatedVehicleTypes"] const descriptionTranslations = new Map() for (let j = 0; j < header.length; j++) { const key = header[j]; @@ -51,7 +54,7 @@ function loadCsv(file): { function run(file, protojson) { const overview_question_answers = [] - const questions: TagRenderingConfigJson[] = [] + const questions: (TagRenderingConfigJson & {"id": string})[] = [] const filterOptions: { question: any, osmTags?: string } [] = [ { question: { @@ -62,10 +65,11 @@ function run(file, protojson) { ] const entries = loadCsv(file) - for (const e of entries) { + for (let i = 0; i < entries.length; i++){ + const e = entries[i]; const txt = { - en: ` ${e.description.get("en")}`, - nl: ` ${e.description.get("nl")}` + en: `
${e.description.get("en")}
`, + nl: `
${e.description.get("nl")}
` } const json = { if: `${e.key}=1`, @@ -73,9 +77,26 @@ function run(file, protojson) { then: txt, } - if (e.countryWhiteList !== undefined && e.countryWhiteList.length > 0) { + if(e.countryWhiteList.length > 0 && e.countryBlackList.length > 0){ + throw "Error for type "+e.key+": don't defined both a whitelist and a blacklist" + } + if (e.countryWhiteList.length > 0) { + // This is a 'hideInAnswer', thus _reverse_ logic! const countries = e.countryWhiteList.map(country => "_country!=" + country) //HideInAnswer if it is in the wrong country json["hideInAnswer"] = {or: countries} + }else if (e.countryBlackList .length > 0) { + const countries = e.countryBlackList.map(country => "_country=" + country) //HideInAnswer if it is in the wrong country + json["hideInAnswer"] = {or: countries} + } + + if(e.associatedVehicleTypes?.length > 0 && e.associatedVehicleTypes.indexOf("*") < 0){ + // This plug only occurs if some vehicle specific vehicle type is present. + // IF all of the needed vehicle types are explicitly NO, then we hide this type as well + let hideInAnswer : any = {and: [].concat(...e.associatedVehicleTypes.map(neededVehicle => [neededVehicle+"~*", neededVehicle+"!=yes"]))} + if(json["hideInAnswer"] !== undefined){ + hideInAnswer = {or: [json["hideInAnswer"], hideInAnswer]} + } + json["hideInAnswer"] = hideInAnswer } overview_question_answers.push(json) @@ -94,6 +115,7 @@ function run(file, protojson) { const descrWithImage_nl = `${e.description.get("nl")} ` questions.push({ + "id":"plugs-"+i, question: { en: `How much plugs of type ${descrWithImage_en} are available here?`, nl: `Hoeveel stekkers van type ${descrWithImage_nl} heeft dit oplaadpunt?`, @@ -112,6 +134,7 @@ function run(file, protojson) { }) questions.push({ + "id":"voltage-"+i, question: { en: `What voltage do the plugs with ${descrWithImage_en} offer?`, nl: `Welke spanning levert de stekker van type ${descrWithImage_nl}` @@ -140,6 +163,7 @@ function run(file, protojson) { questions.push({ + "id":"current-"+i, question: { en: `What current do the plugs with ${descrWithImage_en} offer?`, nl: `Welke stroom levert de stekker van type ${descrWithImage_nl}?`, @@ -168,6 +192,7 @@ function run(file, protojson) { questions.push({ + "id":"power-output-"+i, question: { en: `What power output does a single plug of type ${descrWithImage_en} offer?`, nl: `Welk vermogen levert een enkele stekker van type ${descrWithImage_nl}?`, @@ -204,6 +229,7 @@ function run(file, protojson) { } const toggles = { + "id":"Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -213,10 +239,22 @@ function run(file, protojson) { questions.unshift(toggles) const stringified = questions.map(q => JSON.stringify(q, null, " ")) - let proto = readFileSync(protojson, "utf8") - proto = proto.replace("$$$", stringified.join(",\n") + ",") - proto = JSON.parse(proto) + let protoString = readFileSync(protojson, "utf8") + + protoString = protoString.replace("{\"id\": \"$$$\"}", stringified.join(",\n")) + const proto = JSON.parse(protoString) + proto.tagRenderings.forEach(tr => { + if(typeof tr === "string"){ + return; + } + if(tr["id"] === undefined || typeof tr["id"] !== "string"){ + console.error(tr) + throw "Every tagrendering should have an id, acting as comment" + } + }) + proto["filter"].push({ + id:"connection_type", options: filterOptions }) @@ -273,7 +311,6 @@ function run(file, protojson) { proto["units"] = [] } proto["units"].push(...extraUnits) - writeFileSync("charging_station.json", JSON.stringify(proto, undefined, " ")) } @@ -302,22 +339,51 @@ async function queryTagInfo(file, type, clean: ((s: string) => string)) { } const countsArray = Array.from(counts.keys()) countsArray.sort() - // console.log(`${e.key}:${type} = ${countsArray.join(";")}`) - console.log(`${countsArray.join(";")}`) + console.log(`${e.key}:${type} = ${countsArray.join(";")}`) + } +} + +/** + * Adds the translations into the 'newConfig' object + * @param origPath + * @param newConfig + */ +function mergeTranslations(origPath, newConfig: LayerConfigJson){ + const oldFile = JSON.parse(readFileSync(origPath, "utf-8")) + const newFile = newConfig + const renderingsOld = oldFile.tagRenderings + delete oldFile.tagRenderings + const newRenderings = newFile.tagRenderings + Utils.Merge(oldFile, newFile) + + for (const oldRendering of renderingsOld) { + + const oldRenderingName = oldRendering["id"] + if(oldRenderingName === undefined){ + continue + } + const applicable = newRenderings.filter(r => r["id"] === oldRenderingName)[0] + if(applicable === undefined){ + continue; + } + Utils.Merge(oldRendering, applicable) } } try { + console.log("Generating the charging_station.json file") run("types.csv", "charging_station.protojson") - // queryTagInfo("types.csv","voltage", true) - // queryTagInfo("types.csv", "current", true) - /* queryTagInfo("types.csv", "output", s => { + /*/ + queryTagInfo("types.csv","voltage", s => s.trim()) + queryTagInfo("types.csv", "current", s => s.trim()) + queryTagInfo("types.csv", "output", s => { if(s.endsWith("kW")){ s = s.substring(0, s.length - 2) } s = s.trim() return s + " kW" - })*/ + }) + //*/ } catch (e) { console.error(e) diff --git a/assets/layers/charging_station/license_info.json b/assets/layers/charging_station/license_info.json index 96d5a1ef7..0445cb394 100644 --- a/assets/layers/charging_station/license_info.json +++ b/assets/layers/charging_station/license_info.json @@ -108,5 +108,15 @@ "sources": [ "https://upload.wikimedia.org/wikipedia/commons/2/20/UnderCon_icon.svg" ] + }, + { + "path": "usb_port.svg", + "license": "CC-BY", + "authors": [ + "Ryan Dardis" + ], + "sources": [ + "https://thenounproject.com/term/usb-port/94768/" + ] } ] \ No newline at end of file diff --git a/assets/layers/charging_station/types.csv b/assets/layers/charging_station/types.csv index 5cf989085..ad7f9cc17 100644 --- a/assets/layers/charging_station/types.csv +++ b/assets/layers/charging_station/types.csv @@ -1,10 +1,15 @@ -key,image,description:en,countryWhitelist,commonVoltages,commonCurrents,commonOutputs,description:nl -socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F) -socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E) -socket:chademo,Chademo_type4.svg,Chademo,,500,120,50 kW, -socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772) -socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772) -socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;, -socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,480,125;350,120 kW;150 kW;250 kW, -socket:type2,Type2_socket.svg,Type 2 (mennekes),,230;400,16;32,11 kW;22 kW, -socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,500;920,125;350,50 kW, +key,image,description:en,countryWhiteList,countryBlackList,commonVoltages,commonCurrents,commonOutputs,description:nl,associatedVehicleTypes +socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F),* +socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E),* +socket:chademo,Chademo_type4.svg,Chademo,,,500,120,50 kW,Chademo,car;motorcar;hgv;bus +socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772),car;motorcar;hgv;bus +socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772),car;motorcar;hgv;bus +socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;,Type 1 CCS (ook gekend als Type 1 Combo),car;motorcar;hgv;bus +socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,,480,125;350,120 kW;150 kW;250 kW,Tesla Supercharger,car;motorcar;hgv;bus +socket:type2,Type2_socket.svg,Type 2 (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 (mennekes),car;motorcar;hgv;bus +socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,,500;920,125;350,50 kW,Type 2 CCS (mennekes),car;motorcar;hgv;bus +socket:type2_cable,Type2_tethered.svg,Type 2 with cable (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 met kabel (J1772),car;motorcar;hgv;bus +socket:tesla_supercharger_ccs,Type2_CCS.svg,Tesla Supercharger CCS (a branded type2_css),,,500;920,125;350,50 kW,Tesla Supercharger CCS (een type2 CCS met Tesla-logo),car;motorcar;hgv;bus +socket:tesla_destination,Tesla-hpwc-model-s.svg,Tesla Supercharger (destination),us,,480,125;350,120 kW;150 kW;250 kW,Tesla Supercharger (destination),car;motorcar;hgv;bus +socket:tesla_destination,Type2_tethered.svg,Tesla supercharger (destination (A Type 2 with cable branded as tesla),,us,230;400,16;32,11 kW;22 kW,Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo),car;motorcar;hgv;bus +socket:USB-A,usb_port.svg,USB to charge phones and small electronics,,,5,1;2,5W;10W,USB om GSMs en kleine electronica op te laden,* diff --git a/assets/layers/charging_station/usb_port.svg b/assets/layers/charging_station/usb_port.svg new file mode 100644 index 000000000..f813f20f0 --- /dev/null +++ b/assets/layers/charging_station/usb_port.svg @@ -0,0 +1,74 @@ + +image/svg+xml \ No newline at end of file diff --git a/assets/layers/cluster_style/cluster_style.json b/assets/layers/cluster_style/cluster_style.json new file mode 100644 index 000000000..d6b68d113 --- /dev/null +++ b/assets/layers/cluster_style/cluster_style.json @@ -0,0 +1,36 @@ +{ + "id": "cluster_style", + "description": "The style for the clustering in all themes.", + "source": { + "osmTags": "tileId~*" + }, + "color": { + "render": "#3c3", + "mappings": [ + { + "if": "count>200", + "then": "#f33" + }, + { + "if": "count>100", + "then": "#c93" + }, + { + "if": "count>50", + "then": "#cc3" + } + ] + }, + "width": { + "render": "1" + }, + "label": { + "render": "
{count}
", + "mappings": [ + { + "if": "count>99", + "then": "
>99
" + } + ] + } +} \ No newline at end of file diff --git a/assets/layers/crossings/crossings.json b/assets/layers/crossings/crossings.json index 876656d1f..85ee0a38a 100644 --- a/assets/layers/crossings/crossings.json +++ b/assets/layers/crossings/crossings.json @@ -1,324 +1,332 @@ { - "id": "crossings", - "name": { - "en": "Crossings", - "nl": "Oversteekplaatsen" - }, - "description": { - "en": "Crossings for pedestrians and cyclists", - "nl": "Oversteekplaatsen voor voetgangers en fietsers" - }, - "source": { - "osmTags": { - "or": [ - "highway=traffic_signals", - "highway=crossing" - ] - } - }, - "minzoom": 17, - "title": { - "render": { - "en": "Crossing", - "nl": "Oversteekplaats" + "id": "crossings", + "name": { + "en": "Crossings", + "nl": "Oversteekplaatsen" }, - "mappings": [ - { - "if": "highway=traffic_signals", - "then": { - "en": "Traffic signal", - "nl": "Verkeerslicht" - } - }, - { - "if": "crossing=traffic_signals", - "then": { - "en": "Crossing with traffic signals", - "nl": "Oversteektplaats met verkeerslichten" - } - } - ] - }, - "icon": { - "render": "./assets/layers/crossings/pedestrian_crossing.svg", - "mappings": [ - { - "if": { - "or": [ - "highway=traffic_signals", - "crossing=traffic_signals" - ] - }, - "then": "./assets/layers/crossings/traffic_lights.svg" - } - ] - }, - "width": "5", - "presets": [ - { - "title": { - "en": "Crossing", - "nl": "Oversteekplaats" - }, - "tags": [ - "highway=crossing" - ], - "description": { - "en": "Crossing for pedestrians and/or cyclists", - "nl": "Oversteekplaats voor voetgangers en/of fietsers" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } + "description": { + "en": "Crossings for pedestrians and cyclists", + "nl": "Oversteekplaatsen voor voetgangers en fietsers" }, - { - "title": { - "en": "Traffic signal", - "nl": "Verkeerslicht" - }, - "tags": [ - "highway=traffic_signals" - ], - "description": { - "en": "Traffic signal on a road", - "nl": "Verkeerslicht op een weg" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - } - ], - "tagRenderings": [ - { - "question": { - "en": "What kind of crossing is this?", - "nl": "Wat voor oversteekplaats is dit?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "crossing=uncontrolled", - "then": { - "en": "Crossing, without traffic lights", - "nl": "Oversteekplaats, zonder verkeerslichten" - } - }, - { - "if": "crossing=traffic_signals", - "then": { - "en": "Crossing with traffic signals", - "nl": "Oversteekplaats met verkeerslichten" - } - }, - { - "if": "crossing=zebra", - "then": { - "en": "Zebra crossing", - "nl": "Zebrapad" - }, - "hideInAnswer": true + "source": { + "osmTags": { + "or": [ + "highway=traffic_signals", + "highway=crossing" + ] } - ] }, - { - "question": { - "en": "Is this is a zebra crossing?", - "nl": "Is dit een zebrapad?" - }, - "condition": "crossing=uncontrolled", - "mappings": [ - { - "if": "crossing_ref=zebra", - "then": { - "en": "This is a zebra crossing", - "nl": "Dit is een zebrapad" - } + "minzoom": 17, + "title": { + "render": { + "en": "Crossing", + "nl": "Oversteekplaats" }, - { - "if": "crossing_ref=", - "then": { - "en": "This is not a zebra crossing", - "nl": "Dit is geen zebrapad" - } - } - ] - }, - { - "question": { - "en": "Is this crossing also for bicycles?", - "nl": "Is deze oversteekplaats ook voor fietsers" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "bicycle=yes", - "then": { - "en": "A cyclist can use this crossing", - "nl": "Een fietser kan deze oversteekplaats gebruiken" - } - }, - { - "if": "bicycle=no", - "then": { - "en": "A cyclist can not use this crossing", - "nl": "Een fietser kan deze oversteekplaats niet gebruiken" - } - } - ] - }, - { - "question": { - "en": "Does this crossing have an island in the middle?", - "nl": "Heeft deze oversteekplaats een verkeerseiland in het midden?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "crossing:island=yes", - "then": { - "en": "This crossing has an island in the middle", - "nl": "Deze oversteekplaats heeft een verkeerseiland in het midden" - } - }, - { - "if": "crossing:island=no", - "then": { - "en": "This crossing does not have an island in the middle", - "nl": "Deze oversteekplaats heeft geen verkeerseiland in het midden" - } - } - ] - }, - { - "question": { - "en": "Does this crossing have tactile paving?", - "nl": "Heeft deze oversteekplaats een geleidelijn?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "tactile_paving=yes", - "then": { - "en": "This crossing has tactile paving", - "nl": "Deze oversteekplaats heeft een geleidelijn" - } - }, - { - "if": "tactile_paving=no", - "then": { - "en": "This crossing does not have tactile paving", - "nl": "Deze oversteekplaats heeft geen geleidelijn" - } - }, - { - "if": "tactile_paving=incorrect", - "then": { - "en": "This crossing has tactile paving, but is not correct", - "nl": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Does this traffic light have a button to request green light?", - "nl": "Heeft dit verkeerslicht een knop voor groen licht?" - }, - "condition": { - "or": [ - "highway=traffic_signals", - "crossing=traffic_signals" + "mappings": [ + { + "if": "highway=traffic_signals", + "then": { + "en": "Traffic signal", + "nl": "Verkeerslicht" + } + }, + { + "if": "crossing=traffic_signals", + "then": { + "en": "Crossing with traffic signals", + "nl": "Oversteektplaats met verkeerslichten" + } + } ] - }, - "mappings": [ - { - "if": "button_operated=yes", - "then": { - "en": "This traffic light has a button to request green light", - "nl": "Dit verkeerslicht heeft een knop voor groen licht" - } - }, - { - "if": "button_operated=no", - "then": { - "en": "This traffic light does not have a button to request green light", - "nl": "Dit verkeerlicht heeft geen knop voor groen licht" - } - } - ] }, - { - "question": { - "en": "Can a cyclist turn right when the light is red?", - "nl": "Mag een fietser rechtsaf slaan als het licht rood is?" - }, - "condition": "highway=traffic_signals", - "mappings": [ - { - "if": "red_turn:right:bicycle=yes", - "then": { - "en": "A cyclist can turn right if the light is red ", - "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is " - }, - "hideInAnswer": "_country!=be" - }, - { - "if": "red_turn:right:bicycle=yes", - "then": { - "en": "A cyclist can turn right if the light is red", - "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "red_turn:right:bicycle=no", - "then": { - "en": "A cyclist can not turn right if the light is red", - "nl": "Een fietser mag niet rechtsaf slaan als het licht rood is" - } - } - ] + "icon": { + "render": "./assets/layers/crossings/pedestrian_crossing.svg", + "mappings": [ + { + "if": { + "or": [ + "highway=traffic_signals", + "crossing=traffic_signals" + ] + }, + "then": "./assets/layers/crossings/traffic_lights.svg" + } + ] }, - { - "question": { - "en": "Can a cyclist go straight on when the light is red?", - "nl": "Mag een fietser rechtdoor gaan als het licht rood is?" - }, - "condition": "highway=traffic_signals", - "mappings": [ + "width": "5", + "presets": [ { - "if": "red_turn:straight:bicycle=yes", - "then": { - "en": "A cyclist can go straight on if the light is red ", - "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is " - }, - "hideInAnswer": "_country!=be" + "title": { + "en": "Crossing", + "nl": "Oversteekplaats" + }, + "tags": [ + "highway=crossing" + ], + "description": { + "en": "Crossing for pedestrians and/or cyclists", + "nl": "Oversteekplaats voor voetgangers en/of fietsers" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } }, { - "if": "red_turn:straight:bicycle=yes", - "then": { - "en": "A cyclist can go straight on if the light is red", - "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "red_turn:straight:bicycle=no", - "then": { - "en": "A cyclist can not go straight on if the light is red", - "nl": "Een fietser mag niet rechtdoor gaan als het licht rood is" - } + "title": { + "en": "Traffic signal", + "nl": "Verkeerslicht" + }, + "tags": [ + "highway=traffic_signals" + ], + "description": { + "en": "Traffic signal on a road", + "nl": "Verkeerslicht op een weg" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } } - ] - } - ] + ], + "tagRenderings": [ + { + "id": "crossing-type", + "question": { + "en": "What kind of crossing is this?", + "nl": "Wat voor oversteekplaats is dit?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "crossing=uncontrolled", + "then": { + "en": "Crossing, without traffic lights", + "nl": "Oversteekplaats, zonder verkeerslichten" + } + }, + { + "if": "crossing=traffic_signals", + "then": { + "en": "Crossing with traffic signals", + "nl": "Oversteekplaats met verkeerslichten" + } + }, + { + "if": "crossing=zebra", + "then": { + "en": "Zebra crossing", + "nl": "Zebrapad" + }, + "hideInAnswer": true + } + ] + }, + { + "id": "crossing-is-zebra", + "question": { + "en": "Is this is a zebra crossing?", + "nl": "Is dit een zebrapad?" + }, + "condition": "crossing=uncontrolled", + "mappings": [ + { + "if": "crossing_ref=zebra", + "then": { + "en": "This is a zebra crossing", + "nl": "Dit is een zebrapad" + } + }, + { + "if": "crossing_ref=", + "then": { + "en": "This is not a zebra crossing", + "nl": "Dit is geen zebrapad" + } + } + ] + }, + { + "id": "crossing-bicycle-allowed", + "question": { + "en": "Is this crossing also for bicycles?", + "nl": "Is deze oversteekplaats ook voor fietsers" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "bicycle=yes", + "then": { + "en": "A cyclist can use this crossing", + "nl": "Een fietser kan deze oversteekplaats gebruiken" + } + }, + { + "if": "bicycle=no", + "then": { + "en": "A cyclist can not use this crossing", + "nl": "Een fietser kan deze oversteekplaats niet gebruiken" + } + } + ] + }, + { + "id": "crossing-has-island", + "question": { + "en": "Does this crossing have an island in the middle?", + "nl": "Heeft deze oversteekplaats een verkeerseiland in het midden?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "crossing:island=yes", + "then": { + "en": "This crossing has an island in the middle", + "nl": "Deze oversteekplaats heeft een verkeerseiland in het midden" + } + }, + { + "if": "crossing:island=no", + "then": { + "en": "This crossing does not have an island in the middle", + "nl": "Deze oversteekplaats heeft geen verkeerseiland in het midden" + } + } + ] + }, + { + "id": "crossing-tactile", + "question": { + "en": "Does this crossing have tactile paving?", + "nl": "Heeft deze oversteekplaats een geleidelijn?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "tactile_paving=yes", + "then": { + "en": "This crossing has tactile paving", + "nl": "Deze oversteekplaats heeft een geleidelijn" + } + }, + { + "if": "tactile_paving=no", + "then": { + "en": "This crossing does not have tactile paving", + "nl": "Deze oversteekplaats heeft geen geleidelijn" + } + }, + { + "if": "tactile_paving=incorrect", + "then": { + "en": "This crossing has tactile paving, but is not correct", + "nl": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." + }, + "hideInAnswer": true + } + ] + }, + { + "id": "crossing-button", + "question": { + "en": "Does this traffic light have a button to request green light?", + "nl": "Heeft dit verkeerslicht een knop voor groen licht?" + }, + "condition": { + "or": [ + "highway=traffic_signals", + "crossing=traffic_signals" + ] + }, + "mappings": [ + { + "if": "button_operated=yes", + "then": { + "en": "This traffic light has a button to request green light", + "nl": "Dit verkeerslicht heeft een knop voor groen licht" + } + }, + { + "if": "button_operated=no", + "then": { + "en": "This traffic light does not have a button to request green light", + "nl": "Dit verkeerlicht heeft geen knop voor groen licht" + } + } + ] + }, + { + "id": "crossing-right-turn-through-red", + "question": { + "en": "Can a cyclist turn right when the light is red?", + "nl": "Mag een fietser rechtsaf slaan als het licht rood is?" + }, + "condition": "highway=traffic_signals", + "mappings": [ + { + "if": "red_turn:right:bicycle=yes", + "then": { + "en": "A cyclist can turn right if the light is red ", + "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "red_turn:right:bicycle=yes", + "then": { + "en": "A cyclist can turn right if the light is red", + "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "red_turn:right:bicycle=no", + "then": { + "en": "A cyclist can not turn right if the light is red", + "nl": "Een fietser mag niet rechtsaf slaan als het licht rood is" + } + } + ] + }, + { + "id": "crossing-continue-through-red", + "question": { + "en": "Can a cyclist go straight on when the light is red?", + "nl": "Mag een fietser rechtdoor gaan als het licht rood is?" + }, + "condition": "highway=traffic_signals", + "mappings": [ + { + "if": "red_turn:straight:bicycle=yes", + "then": { + "en": "A cyclist can go straight on if the light is red ", + "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "red_turn:straight:bicycle=yes", + "then": { + "en": "A cyclist can go straight on if the light is red", + "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "red_turn:straight:bicycle=no", + "then": { + "en": "A cyclist can not go straight on if the light is red", + "nl": "Een fietser mag niet rechtdoor gaan als het licht rood is" + } + } + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index 959dfa03c..2b10d7ebc 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -1,1170 +1,1177 @@ { - "id": "cycleways_and_roads", - "name": { - "en": "Cycleways and roads", - "nl": "Fietspaden, straten en wegen" - }, - "minzoom": 16, - "source": { - "osmTags": { - "or": [ - "highway=cycleway", - "cycleway=lane", - "cycleway=shared_lane", - "cycleway=track", - "cyclestreet=yes", - "highway=residential", - "highway=tertiary", - "highway=unclassified", - "highway=primary", - "highway=secondary", - { - "and": [ - "highway=path", - "bicycle=designated" - ] - } - ] - } - }, - "calculatedTags": [ - "_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')" - ], - "title": { - "render": { - "en": "Cycleways", - "nl": "Fietspaden" + "id": "cycleways_and_roads", + "name": { + "en": "Cycleways and roads", + "nl": "Fietspaden, straten en wegen" }, - "mappings": [ - { - "if": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "then": { - "nl": "Fietsweg", - "en": "Cycleway" - } - }, - { - "if": "cycleway=shared_lane", - "then": { - "nl": "Fietssuggestiestrook", - "en": "Shared lane" - } - }, - { - "if": "cycleway=lane", - "then": { - "nl": "Fietsstrook", - "en": "Bike lane" - } - }, - { - "if": "cycleway=track", - "then": { - "en": "Cycleway next to the road", - "nl": "Fietsweg naast de weg" - } - }, - { - "if": "cyclestreet=yes", - "then": { - "nl": "Fietsstraat", - "en": "Cyclestreet" - } - } - ] - }, - "description": {}, - "tagRenderings": [ - { - "#": "Cycleway type for a road", - "question": { - "en": "What kind of cycleway is here?", - "nl": "Wat voor fietspad is hier?" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "cycleway=shared_lane", - "then": { - "en": "There is a shared lane", - "nl": "Er is een fietssuggestiestrook" - } - }, - { - "if": "cycleway=lane", - "then": { - "en": "There is a lane next to the road (separated with paint)", - "nl": "Er is een fietspad aangrenzend aan de weg (gescheiden met verf)" - } - }, - { - "if": "cycleway=track", - "then": { - "en": "There is a track, but no cycleway drawn separately from this road on the map.", - "nl": "Er is een fietspad (los van de weg), maar geen fietspad afzonderlijk getekend naast deze weg." - } - }, - { - "if": "cycleway=separate", - "then": { - "en": "There is a separately drawn cycleway", - "nl": "Er is een apart getekend fietspad." - } - }, - { - "if": "cycleway=no", - "then": { - "en": "There is no cycleway", - "nl": "Er is geen fietspad aanwezig" - }, - "hideInAnswer": "cycleway=opposite" - }, - { - "if": "cycleway=no", - "then": { - "en": "There is no cycleway", - "nl": "Er is geen fietspad aanwezig" - }, - "hideInAnswer": "cycleway!=opposite", - "addExtraTags": [ - "oneway:bicycle=no", - "fixme=Changed from cycleway=opposite" - ] - } - ] - }, - { - "#": "is lit?", - "question": { - "en": "Is this street lit?", - "nl": "Is deze weg verlicht?" - }, - "mappings": [ - { - "if": "lit=yes", - "then": { - "en": "This street is lit", - "nl": "Deze weg is verlicht" - } - }, - { - "if": "lit=no", - "then": { - "en": "This road is not lit", - "nl": "Deze weg is niet verlicht" - } - }, - { - "if": "lit=sunset-sunrise", - "then": { - "en": "This road is lit at night", - "nl": "Deze weg is 's nachts verlicht" - }, - "hideInAnswer": true - }, - { - "if": "lit=24/7", - "then": { - "en": "This road is lit 24/7", - "nl": "Deze weg is 24/7 verlicht" - } - } - ] - }, - { - "#": "Is this a cyclestreet? (For a road)", - "question": { - "en": "Is this a cyclestreet?", - "nl": "Is dit een fietsstraat?" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "cyclestreet=yes", - "then": { - "en": "This is a cyclestreet, and a 30km/h zone.", - "nl": "Dit is een fietsstraat, en dus een 30km/h zone" - }, - "addExtraTags": [ - "overtaking:motor_vehicle=no", - "maxspeed=30" - ], - "hideInAnswer": "_country!=be" - }, - { - "if": "cyclestreet=yes", - "then": { - "en": "This is a cyclestreet", - "nl": "Dit is een fietsstraat" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "cyclestreet=", - "then": { - "en": "This is not a cyclestreet.", - "nl": "Dit is geen fietsstraat" - }, - "addExtraTags": [ - "overtaking:motor_vehicle=" - ] - } - ] - }, - { - "#": "Maxspeed (for road)", - "render": { - "en": "The maximum speed on this road is {maxspeed} km/h", - "nl": "De maximumsnelheid op deze weg is {maxspeed} km/u" - }, - "freeform": { - "key": "maxspeed", - "type": "nat" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "maxspeed=20", - "then": { - "en": "The maximum speed is 20 km/h", - "nl": "De maximumsnelheid is 20 km/u" - } - }, - { - "if": "maxspeed=30", - "then": { - "en": "The maximum speed is 30 km/h", - "nl": "De maximumsnelheid is 30 km/u" - } - }, - { - "if": "maxspeed=50", - "then": { - "en": "The maximum speed is 50 km/h", - "nl": "De maximumsnelheid is 50 km/u" - } - }, - { - "if": "maxspeed=70", - "then": { - "en": "The maximum speed is 70 km/h", - "nl": "De maximumsnelheid is 70 km/u" - } - }, - { - "if": "maxspeed=90", - "then": { - "en": "The maximum speed is 90 km/h", - "nl": "De maximumsnelheid is 90 km/u" - } - } - ], - "question": { - "en": "What is the maximum speed in this street?", - "nl": "Wat is de maximumsnelheid in deze straat?" - } - }, - { - "#": "Cycleway:surface", - "render": { - "en": "This cyleway is made of {cycleway:surface}", - "nl": "Dit fietspad is gemaakt van {cycleway:surface}" - }, - "freeform": { - "key": "cycleway:surface" - }, - "condition": { - "or": [ - "cycleway=shared_lane", - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:surface=unpaved", - "then": { - "en": "This cycleway is unpaved", - "nl": "Dit fietspad is onverhard" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=paved", - "then": { - "en": "This cycleway is paved", - "nl": "Dit fietspad is geplaveid" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=asphalt", - "then": { - "en": "This cycleway is made of asphalt", - "nl": "Dit fietspad is gemaakt van asfalt" - } - }, - { - "if": "cycleway:surface=paving_stones", - "then": { - "en": "This cycleway is made of smooth paving stones", - "nl": "Dit fietspad is gemaakt van straatstenen" - } - }, - { - "if": "cycleway:surface=concrete", - "then": { - "en": "This cycleway is made of concrete", - "nl": "Dit fietspad is gemaakt van beton" - } - }, - { - "if": "cycleway:surface=cobblestone", - "then": { - "en": "This cycleway is made of cobblestone (unhewn or sett)", - "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=unhewn_cobblestone", - "then": { - "en": "This cycleway is made of raw, natural cobblestone", - "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" - } - }, - { - "if": "cycleway:surface=sett", - "then": { - "en": "This cycleway is made of flat, square cobblestone", - "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" - } - }, - { - "if": "cycleway:surface=wood", - "then": { - "en": "This cycleway is made of wood", - "nl": "Dit fietspad is gemaakt van hout" - } - }, - { - "if": "cycleway:surface=gravel", - "then": { - "en": "This cycleway is made of gravel", - "nl": "Dit fietspad is gemaakt van grind" - } - }, - { - "if": "cycleway:surface=fine_gravel", - "then": { - "en": "This cycleway is made of fine gravel", - "nl": "Dit fietspad is gemaakt van fijn grind" - } - }, - { - "if": "cycleway:surface=pebblestone", - "then": { - "en": "This cycleway is made of pebblestone", - "nl": "Dit fietspad is gemaakt van kiezelsteentjes" - } - }, - { - "if": "cycleway:surface=ground", - "then": { - "en": "This cycleway is made from raw ground", - "nl": "Dit fietspad is gemaakt van aarde" - } - } - ], - "question": { - "en": "What is the surface of the cycleway made from?", - "nl": "Waaruit is het oppervlak van het fietspad van gemaakt?" - } - }, - { - "#": "Cycleway:smoothness", - "question": { - "en": "What is the smoothness of this cycleway?", - "nl": "Wat is de kwaliteit van dit fietspad?" - }, - "condition": { - "or": [ - "cycleway=shared_lane", - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:smoothness=excellent", - "then": { - "en": "Usable for thin rollers: rollerblade, skateboard", - "nl": "Geschikt voor fijne rollers: rollerblade, skateboard" - } - }, - { - "if": "cycleway:smoothness=good", - "then": { - "en": "Usable for thin wheels: racing bike", - "nl": "Geschikt voor fijne wielen: racefiets" - } - }, - { - "if": "cycleway:smoothness=intermediate", - "then": { - "en": "Usable for normal wheels: city bike, wheelchair, scooter", - "nl": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" - } - }, - { - "if": "cycleway:smoothness=bad", - "then": { - "en": "Usable for robust wheels: trekking bike, car, rickshaw", - "nl": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" - } - }, - { - "if": "cycleway:smoothness=very_bad", - "then": { - "en": "Usable for vehicles with high clearance: light duty off-road vehicle", - "nl": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" - } - }, - { - "if": "cycleway:smoothness=horrible", - "then": { - "en": "Usable for off-road vehicles: heavy duty off-road vehicle", - "nl": "Geschikt voor terreinwagens: zware terreinwagen" - } - }, - { - "if": "cycleway:smoothness=very_horrible", - "then": { - "en": "Usable for specialized off-road vehicles: tractor, ATV", - "nl": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" - } - }, - { - "if": "cycleway:smoothness=impassable", - "then": { - "en": "Impassable / No wheeled vehicle", - "nl": "Niet geschikt voor voertuigen met wielen" - } - } - ] - }, - { - "#": "Surface of the road", - "render": { - "en": "This road is made of {surface}", - "nl": "Deze weg is gemaakt van {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=unpaved", - "then": { - "en": "This cycleway is unhardened", - "nl": "Dit fietspad is onverhard" - }, - "hideInAnswer": true - }, - { - "if": "surface=paved", - "then": { - "en": "This cycleway is paved", - "nl": "Dit fietspad is geplaveid" - }, - "hideInAnswer": true - }, - { - "if": "surface=asphalt", - "then": { - "en": "This cycleway is made of asphalt", - "nl": "Dit fietspad is gemaakt van asfalt" - } - }, - { - "if": "surface=paving_stones", - "then": { - "en": "This cycleway is made of smooth paving stones", - "nl": "Dit fietspad is gemaakt van straatstenen" - } - }, - { - "if": "surface=concrete", - "then": { - "en": "This cycleway is made of concrete", - "nl": "Dit fietspad is gemaakt van beton" - } - }, - { - "if": "surface=cobblestone", - "then": { - "en": "This cycleway is made of cobblestone (unhewn or sett)", - "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" - }, - "hideInAnswer": true - }, - { - "if": "surface=unhewn_cobblestone", - "then": { - "en": "This cycleway is made of raw, natural cobblestone", - "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" - } - }, - { - "if": "surface=sett", - "then": { - "en": "This cycleway is made of flat, square cobblestone", - "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" - } - }, - { - "if": "surface=wood", - "then": { - "en": "This cycleway is made of wood", - "nl": "Dit fietspad is gemaakt van hout" - } - }, - { - "if": "surface=gravel", - "then": { - "en": "This cycleway is made of gravel", - "nl": "Dit fietspad is gemaakt van grind" - } - }, - { - "if": "surface=fine_gravel", - "then": { - "en": "This cycleway is made of fine gravel", - "nl": "Dit fietspad is gemaakt van fijn grind" - } - }, - { - "if": "surface=pebblestone", - "then": { - "en": "This cycleway is made of pebblestone", - "nl": "Dit fietspad is gemaakt van kiezelsteentjes" - } - }, - { - "if": "surface=ground", - "then": { - "en": "This cycleway is made from raw ground", - "nl": "Dit fietspad is gemaakt van aarde" - } - } - ], - "question": { - "en": "What is the surface of the street made from?", - "nl": "Waaruit is het oppervlak van de straat gemaakt?" - } - }, - { - "#": "Surface of the street", - "question": { - "en": "What is the smoothness of this street?", - "nl": "Wat is de kwaliteit van deze straat?" - }, - "condition": { - "or": [ - "cycleway=no", - "highway=cycleway" - ] - }, - "mappings": [ - { - "if": "smoothness=excellent", - "then": { - "en": "Usable for thin rollers: rollerblade, skateboard" - } - }, - { - "if": "smoothness=good", - "then": { - "en": "Usable for thin wheels: racing bike" - } - }, - { - "if": "smoothness=intermediate", - "then": { - "en": "Usable for normal wheels: city bike, wheelchair, scooter" - } - }, - { - "if": "smoothness=bad", - "then": { - "en": "Usable for robust wheels: trekking bike, car, rickshaw" - } - }, - { - "if": "smoothness=very_bad", - "then": { - "en": "Usable for vehicles with high clearance: light duty off-road vehicle" - } - }, - { - "if": "smoothness=horrible", - "then": { - "en": "Usable for off-road vehicles: heavy duty off-road vehicle" - } - }, - { - "if": "smoothness=very_horrible", - "then": { - "en": "Usable for specialized off-road vehicles: tractor, ATV" - } - }, - { - "if": "smoothness=impassable", - "then": { - "en": "Impassable / No wheeled vehicle" - } - } - ] - }, - { - "#": "width:carriageway", - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "render": { - "en": "The carriage width of this road is {width:carriageway}m", - "nl": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" - }, - "freeform": { - "key": "width:carriageway", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - }, - "question": { - "en": "What is the carriage width of this road (in meters)?", - "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" - } - }, - { - "question": { - "en": "What traffic sign does this cycleway have?", - "nl": "Welk verkeersbord heeft dit fietspad?" - }, - "condition": { - "or": [ - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:traffic_sign=BE:D7", - "then": { - "en": "Compulsory cycleway ", - "nl": "Verplicht fietspad " - }, - "hideInAnswer": "_country!=be" - }, - { - "if": "cycleway:traffic_sign~BE:D7;.*", - "then": { - "en": "Compulsory cycleway (with supplementary sign)
", - "nl": "Verplicht fietspad (met onderbord)
" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:traffic_sign=BE:D9", - "then": { - "en": "Segregated foot/cycleway ", - "nl": "Afgescheiden voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:foot=designated", - "cycleway:segregated=yes" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D10", - "then": { - "en": "Unsegregated foot/cycleway ", - "nl": "Gedeeld voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:foot=designated", - "cycleway:segregated=no" - ] - }, - { - "if": "cycleway:traffic_sign=none", - "then": { - "en": "No traffic sign present", - "nl": "Geen verkeersbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "What traffic sign does this cycleway have?", - "nl": "Welk verkeersbord heeft dit fietspad?" - }, - "condition": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "mappings": [ - { - "if": "traffic_sign=BE:D7", - "then": { - "en": "Compulsory cycleway ", - "nl": "Verplicht fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "bicycle=designated", - "mofa=designated", - "moped=yes", - "speed_pedelec=yes" - ] - }, - { - "if": "traffic_sign~BE:D7;.*", - "then": { - "en": "Compulsory cycleway (with supplementary sign)
", - "nl": "Verplicht fietspad (met onderbord)
" - }, - "hideInAnswer": true - }, - { - "if": "traffic_sign=BE:D9", - "then": { - "en": "Segregated foot/cycleway ", - "nl": "Afgescheiden voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "foot=designated", - "bicycle=designated", - "mofa=designated", - "moped=no", - "speed_pedelec=no", - "segregated=yes" - ] - }, - { - "if": "traffic_sign=BE:D10", - "then": { - "en": "Unsegregated foot/cycleway ", - "nl": "Gedeeld voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "foot=designated", - "bicycle=designated", - "mofa=designated", - "moped=no", - "speed_pedelec=no", - "segregated=no" - ] - }, - { - "if": "traffic_sign=none", - "then": { - "en": "No traffic sign present", - "nl": "Geen verkeersbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "Does the traffic sign D7 () have a supplementary sign?", - "nl": "Heeft het verkeersbord D7 () een onderbord?" - }, - "condition": { - "or": [ - "cycleway:traffic_sign=BE:D7", - "cycleway:traffic_sign~BE:D7;.*" - ] - }, - "mappings": [ - { - "if": "cycleway:traffic_sign=BE:D7;BE:M6", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M13", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:speed_pedelec=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M14", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated", - "cycleway:speed_pedelec=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M7", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=no" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M15", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:speed_pedelec=no" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M16", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated", - "cycleway:speed_pedelec=no" - ] - }, - { - "if": "cycleway:traffic_sign:supplementary=none", - "then": { - "en": "No supplementary traffic sign present", - "nl": "Geen onderbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "Does the traffic sign D7 () have a supplementary sign?", - "nl": "Heeft het verkeersbord D7 () een onderbord?" - }, - "condition": { - "or": [ - "traffic_sign=BE:D7", - "traffic_sign~BE:D7;.*" - ] - }, - "mappings": [ - { - "if": "traffic_sign=BE:D7;BE:M6", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M13", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "speed_pedelec=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M14", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated", - "speed_pedelec=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M7", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=no" - ] - }, - { - "if": ":traffic_sign=BE:D7;BE:M15", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "speed_pedelec=no" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M16", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated", - "speed_pedelec=no" - ] - }, - { - "if": "traffic_sign:supplementary=none", - "then": { - "en": "No supplementary traffic sign present", - "nl": "Geen onderbord aanwezig" - } - } - ] - }, - { - "render": { - "en": "The buffer besides this cycleway is {cycleway:buffer} m", - "nl": "De schrikafstand van dit fietspad is {cycleway:buffer} m" - }, - "question": { - "en": "How wide is the gap between the cycleway and the road?", - "nl": "Hoe breed is de ruimte tussen het fietspad en de weg?" - }, - "condition": { - "or": [ - "cycleway=track", - "cycleway=lane" - ] - }, - "freeform": { - "key": "cycleway:buffer", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - } - }, - { - "question": { - "en": "How is this cycleway separated from the road?", - "nl": "Hoe is dit fietspad gescheiden van de weg?" - }, - "condition": { - "or": [ - "cycleway=track", - "cycleway=lane" - ] - }, - "mappings": [ - { - "if": "cycleway:separation=dashed_line", - "then": { - "en": "This cycleway is separated by a dashed line", - "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - } - }, - { - "if": "cycleway:separation=solid_line", - "then": { - "en": "This cycleway is separated by a solid line", - "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - } - }, - { - "if": "cycleway:separation=parking_lane", - "then": { - "en": "This cycleway is separated by a parking lane", - "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" - } - }, - { - "if": "cycleway:separation=kerb", - "then": { - "en": "This cycleway is separated by a kerb", - "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - } - ] - }, - { - "question": { - "en": "How is this cycleway separated from the road?", - "nl": "Hoe is dit fietspad gescheiden van de weg?" - }, - "condition": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "mappings": [ - { - "if": "separation=dashed_line", - "then": { - "en": "This cycleway is separated by a dashed line", - "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - } - }, - { - "if": "separation=solid_line", - "then": { - "en": "This cycleway is separated by a solid line", - "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - } - }, - { - "if": "separation=parking_lane", - "then": { - "en": "This cycleway is separated by a parking lane", - "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" - } - }, - { - "if": "separation=kerb", - "then": { - "en": "This cycleway is separated by a kerb", - "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/cycle_infra/bicycleway.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "rgba(170, 170, 170, 0.7)", - "mappings": [ - { - "if": "highway=cycleway", - "then": "rgba(0, 189, 141, 0.7)" - }, - { - "if": "highway=path", - "then": "rgba(204, 74, 207, 0.7)" - }, - { - "if": "cycleway=track", - "then": "rgba(113, 3, 200, 0.7)" - }, - { - "if": "cycleway=shared_lane", - "then": "rgba(74, 59, 247, 0.7)" - }, - { - "if": "cycleway=lane", - "then": "rgba(254, 155, 6, 0.9)" - }, - { - "if": "cyclestreet=yes", - "then": "rgba(57, 159, 191, 0.7)" - } - ] - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": { - "or": [ - "oneway=yes", - { - "or": [ + "minzoom": 16, + "source": { + "osmTags": { + "or": [ "highway=cycleway", - "highway=path" - ] - } - ] + "cycleway=lane", + "cycleway=shared_lane", + "cycleway=track", + "cyclestreet=yes", + "highway=residential", + "highway=tertiary", + "highway=unclassified", + "highway=primary", + "highway=secondary", + { + "and": [ + "highway=path", + "bicycle=designated" + ] + } + ] + } + }, + "calculatedTags": [ + "_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')" + ], + "title": { + "render": { + "en": "Cycleways", + "nl": "Fietspaden" }, - "then": "" - }, - { - "if": "cycleway=track", - "then": "" - }, - { - "if": "cycleway=shared_lane", - "then": "15 30" - }, - { - "if": "cycleway=lane", - "then": "25 15 15 15 25" - }, - { - "if": "cyclestreet=yes", - "then": "" - } - ] - } + "mappings": [ + { + "if": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "then": { + "nl": "Fietsweg", + "en": "Cycleway" + } + }, + { + "if": "cycleway=shared_lane", + "then": { + "nl": "Fietssuggestiestrook", + "en": "Shared lane" + } + }, + { + "if": "cycleway=lane", + "then": { + "nl": "Fietsstrook", + "en": "Bike lane" + } + }, + { + "if": "cycleway=track", + "then": { + "en": "Cycleway next to the road", + "nl": "Fietsweg naast de weg" + } + }, + { + "if": "cyclestreet=yes", + "then": { + "nl": "Fietsstraat", + "en": "Cyclestreet" + } + } + ] + }, + "description": {}, + "tagRenderings": [ + { + "question": { + "en": "What kind of cycleway is here?", + "nl": "Wat voor fietspad is hier?" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "cycleway=shared_lane", + "then": { + "en": "There is a shared lane", + "nl": "Er is een fietssuggestiestrook" + } + }, + { + "if": "cycleway=lane", + "then": { + "en": "There is a lane next to the road (separated with paint)", + "nl": "Er is een fietspad aangrenzend aan de weg (gescheiden met verf)" + } + }, + { + "if": "cycleway=track", + "then": { + "en": "There is a track, but no cycleway drawn separately from this road on the map.", + "nl": "Er is een fietspad (los van de weg), maar geen fietspad afzonderlijk getekend naast deze weg." + } + }, + { + "if": "cycleway=separate", + "then": { + "en": "There is a separately drawn cycleway", + "nl": "Er is een apart getekend fietspad." + } + }, + { + "if": "cycleway=no", + "then": { + "en": "There is no cycleway", + "nl": "Er is geen fietspad aanwezig" + }, + "hideInAnswer": "cycleway=opposite" + }, + { + "if": "cycleway=no", + "then": { + "en": "There is no cycleway", + "nl": "Er is geen fietspad aanwezig" + }, + "hideInAnswer": "cycleway!=opposite", + "addExtraTags": [ + "oneway:bicycle=no", + "fixme=Changed from cycleway=opposite" + ] + } + ], + "id": "Cycleway type for a road" + }, + { + "question": { + "en": "Is this street lit?", + "nl": "Is deze weg verlicht?" + }, + "mappings": [ + { + "if": "lit=yes", + "then": { + "en": "This street is lit", + "nl": "Deze weg is verlicht" + } + }, + { + "if": "lit=no", + "then": { + "en": "This road is not lit", + "nl": "Deze weg is niet verlicht" + } + }, + { + "if": "lit=sunset-sunrise", + "then": { + "en": "This road is lit at night", + "nl": "Deze weg is 's nachts verlicht" + }, + "hideInAnswer": true + }, + { + "if": "lit=24/7", + "then": { + "en": "This road is lit 24/7", + "nl": "Deze weg is 24/7 verlicht" + } + } + ], + "id": "is lit?" + }, + { + "question": { + "en": "Is this a cyclestreet?", + "nl": "Is dit een fietsstraat?" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "cyclestreet=yes", + "then": { + "en": "This is a cyclestreet, and a 30km/h zone.", + "nl": "Dit is een fietsstraat, en dus een 30km/h zone" + }, + "addExtraTags": [ + "overtaking:motor_vehicle=no", + "maxspeed=30" + ], + "hideInAnswer": "_country!=be" + }, + { + "if": "cyclestreet=yes", + "then": { + "en": "This is a cyclestreet", + "nl": "Dit is een fietsstraat" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "cyclestreet=", + "then": { + "en": "This is not a cyclestreet.", + "nl": "Dit is geen fietsstraat" + }, + "addExtraTags": [ + "overtaking:motor_vehicle=" + ] + } + ], + "id": "Is this a cyclestreet? (For a road)" + }, + { + "render": { + "en": "The maximum speed on this road is {maxspeed} km/h", + "nl": "De maximumsnelheid op deze weg is {maxspeed} km/u" + }, + "freeform": { + "key": "maxspeed", + "type": "nat" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "maxspeed=20", + "then": { + "en": "The maximum speed is 20 km/h", + "nl": "De maximumsnelheid is 20 km/u" + } + }, + { + "if": "maxspeed=30", + "then": { + "en": "The maximum speed is 30 km/h", + "nl": "De maximumsnelheid is 30 km/u" + } + }, + { + "if": "maxspeed=50", + "then": { + "en": "The maximum speed is 50 km/h", + "nl": "De maximumsnelheid is 50 km/u" + } + }, + { + "if": "maxspeed=70", + "then": { + "en": "The maximum speed is 70 km/h", + "nl": "De maximumsnelheid is 70 km/u" + } + }, + { + "if": "maxspeed=90", + "then": { + "en": "The maximum speed is 90 km/h", + "nl": "De maximumsnelheid is 90 km/u" + } + } + ], + "question": { + "en": "What is the maximum speed in this street?", + "nl": "Wat is de maximumsnelheid in deze straat?" + }, + "id": "Maxspeed (for road)" + }, + { + "render": { + "en": "This cyleway is made of {cycleway:surface}", + "nl": "Dit fietspad is gemaakt van {cycleway:surface}" + }, + "freeform": { + "key": "cycleway:surface" + }, + "condition": { + "or": [ + "cycleway=shared_lane", + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:surface=unpaved", + "then": { + "en": "This cycleway is unpaved", + "nl": "Dit fietspad is onverhard" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=paved", + "then": { + "en": "This cycleway is paved", + "nl": "Dit fietspad is geplaveid" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=asphalt", + "then": { + "en": "This cycleway is made of asphalt", + "nl": "Dit fietspad is gemaakt van asfalt" + } + }, + { + "if": "cycleway:surface=paving_stones", + "then": { + "en": "This cycleway is made of smooth paving stones", + "nl": "Dit fietspad is gemaakt van straatstenen" + } + }, + { + "if": "cycleway:surface=concrete", + "then": { + "en": "This cycleway is made of concrete", + "nl": "Dit fietspad is gemaakt van beton" + } + }, + { + "if": "cycleway:surface=cobblestone", + "then": { + "en": "This cycleway is made of cobblestone (unhewn or sett)", + "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=unhewn_cobblestone", + "then": { + "en": "This cycleway is made of raw, natural cobblestone", + "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" + } + }, + { + "if": "cycleway:surface=sett", + "then": { + "en": "This cycleway is made of flat, square cobblestone", + "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" + } + }, + { + "if": "cycleway:surface=wood", + "then": { + "en": "This cycleway is made of wood", + "nl": "Dit fietspad is gemaakt van hout" + } + }, + { + "if": "cycleway:surface=gravel", + "then": { + "en": "This cycleway is made of gravel", + "nl": "Dit fietspad is gemaakt van grind" + } + }, + { + "if": "cycleway:surface=fine_gravel", + "then": { + "en": "This cycleway is made of fine gravel", + "nl": "Dit fietspad is gemaakt van fijn grind" + } + }, + { + "if": "cycleway:surface=pebblestone", + "then": { + "en": "This cycleway is made of pebblestone", + "nl": "Dit fietspad is gemaakt van kiezelsteentjes" + } + }, + { + "if": "cycleway:surface=ground", + "then": { + "en": "This cycleway is made from raw ground", + "nl": "Dit fietspad is gemaakt van aarde" + } + } + ], + "question": { + "en": "What is the surface of the cycleway made from?", + "nl": "Waaruit is het oppervlak van het fietspad van gemaakt?" + }, + "id": "Cycleway:surface" + }, + { + "question": { + "en": "What is the smoothness of this cycleway?", + "nl": "Wat is de kwaliteit van dit fietspad?" + }, + "condition": { + "or": [ + "cycleway=shared_lane", + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:smoothness=excellent", + "then": { + "en": "Usable for thin rollers: rollerblade, skateboard", + "nl": "Geschikt voor fijne rollers: rollerblade, skateboard" + } + }, + { + "if": "cycleway:smoothness=good", + "then": { + "en": "Usable for thin wheels: racing bike", + "nl": "Geschikt voor fijne wielen: racefiets" + } + }, + { + "if": "cycleway:smoothness=intermediate", + "then": { + "en": "Usable for normal wheels: city bike, wheelchair, scooter", + "nl": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" + } + }, + { + "if": "cycleway:smoothness=bad", + "then": { + "en": "Usable for robust wheels: trekking bike, car, rickshaw", + "nl": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" + } + }, + { + "if": "cycleway:smoothness=very_bad", + "then": { + "en": "Usable for vehicles with high clearance: light duty off-road vehicle", + "nl": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" + } + }, + { + "if": "cycleway:smoothness=horrible", + "then": { + "en": "Usable for off-road vehicles: heavy duty off-road vehicle", + "nl": "Geschikt voor terreinwagens: zware terreinwagen" + } + }, + { + "if": "cycleway:smoothness=very_horrible", + "then": { + "en": "Usable for specialized off-road vehicles: tractor, ATV", + "nl": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" + } + }, + { + "if": "cycleway:smoothness=impassable", + "then": { + "en": "Impassable / No wheeled vehicle", + "nl": "Niet geschikt voor voertuigen met wielen" + } + } + ], + "id": "Cycleway:smoothness" + }, + { + "render": { + "en": "This road is made of {surface}", + "nl": "Deze weg is gemaakt van {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=unpaved", + "then": { + "en": "This cycleway is unhardened", + "nl": "Dit fietspad is onverhard" + }, + "hideInAnswer": true + }, + { + "if": "surface=paved", + "then": { + "en": "This cycleway is paved", + "nl": "Dit fietspad is geplaveid" + }, + "hideInAnswer": true + }, + { + "if": "surface=asphalt", + "then": { + "en": "This cycleway is made of asphalt", + "nl": "Dit fietspad is gemaakt van asfalt" + } + }, + { + "if": "surface=paving_stones", + "then": { + "en": "This cycleway is made of smooth paving stones", + "nl": "Dit fietspad is gemaakt van straatstenen" + } + }, + { + "if": "surface=concrete", + "then": { + "en": "This cycleway is made of concrete", + "nl": "Dit fietspad is gemaakt van beton" + } + }, + { + "if": "surface=cobblestone", + "then": { + "en": "This cycleway is made of cobblestone (unhewn or sett)", + "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" + }, + "hideInAnswer": true + }, + { + "if": "surface=unhewn_cobblestone", + "then": { + "en": "This cycleway is made of raw, natural cobblestone", + "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" + } + }, + { + "if": "surface=sett", + "then": { + "en": "This cycleway is made of flat, square cobblestone", + "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" + } + }, + { + "if": "surface=wood", + "then": { + "en": "This cycleway is made of wood", + "nl": "Dit fietspad is gemaakt van hout" + } + }, + { + "if": "surface=gravel", + "then": { + "en": "This cycleway is made of gravel", + "nl": "Dit fietspad is gemaakt van grind" + } + }, + { + "if": "surface=fine_gravel", + "then": { + "en": "This cycleway is made of fine gravel", + "nl": "Dit fietspad is gemaakt van fijn grind" + } + }, + { + "if": "surface=pebblestone", + "then": { + "en": "This cycleway is made of pebblestone", + "nl": "Dit fietspad is gemaakt van kiezelsteentjes" + } + }, + { + "if": "surface=ground", + "then": { + "en": "This cycleway is made from raw ground", + "nl": "Dit fietspad is gemaakt van aarde" + } + } + ], + "question": { + "en": "What is the surface of the street made from?", + "nl": "Waaruit is het oppervlak van de straat gemaakt?" + }, + "id": "Surface of the road" + }, + { + "question": { + "en": "What is the smoothness of this street?", + "nl": "Wat is de kwaliteit van deze straat?" + }, + "condition": { + "or": [ + "cycleway=no", + "highway=cycleway" + ] + }, + "mappings": [ + { + "if": "smoothness=excellent", + "then": { + "en": "Usable for thin rollers: rollerblade, skateboard" + } + }, + { + "if": "smoothness=good", + "then": { + "en": "Usable for thin wheels: racing bike" + } + }, + { + "if": "smoothness=intermediate", + "then": { + "en": "Usable for normal wheels: city bike, wheelchair, scooter" + } + }, + { + "if": "smoothness=bad", + "then": { + "en": "Usable for robust wheels: trekking bike, car, rickshaw" + } + }, + { + "if": "smoothness=very_bad", + "then": { + "en": "Usable for vehicles with high clearance: light duty off-road vehicle" + } + }, + { + "if": "smoothness=horrible", + "then": { + "en": "Usable for off-road vehicles: heavy duty off-road vehicle" + } + }, + { + "if": "smoothness=very_horrible", + "then": { + "en": "Usable for specialized off-road vehicles: tractor, ATV" + } + }, + { + "if": "smoothness=impassable", + "then": { + "en": "Impassable / No wheeled vehicle" + } + } + ], + "id": "Surface of the street" + }, + { + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "render": { + "en": "The carriage width of this road is {width:carriageway}m", + "nl": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" + }, + "freeform": { + "key": "width:carriageway", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + }, + "question": { + "en": "What is the carriage width of this road (in meters)?", + "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" + }, + "id": "width:carriageway" + }, + { + "id": "cycleway-lane-track-traffic-signs", + "question": { + "en": "What traffic sign does this cycleway have?", + "nl": "Welk verkeersbord heeft dit fietspad?" + }, + "condition": { + "or": [ + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:traffic_sign=BE:D7", + "then": { + "en": "Compulsory cycleway ", + "nl": "Verplicht fietspad " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "cycleway:traffic_sign~BE:D7;.*", + "then": { + "en": "Compulsory cycleway (with supplementary sign)
", + "nl": "Verplicht fietspad (met onderbord)
" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:traffic_sign=BE:D9", + "then": { + "en": "Segregated foot/cycleway ", + "nl": "Afgescheiden voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:foot=designated", + "cycleway:segregated=yes" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D10", + "then": { + "en": "Unsegregated foot/cycleway ", + "nl": "Gedeeld voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:foot=designated", + "cycleway:segregated=no" + ] + }, + { + "if": "cycleway:traffic_sign=none", + "then": { + "en": "No traffic sign present", + "nl": "Geen verkeersbord aanwezig" + } + } + ] + }, + { + "id": "cycleway-traffic-signs", + "question": { + "en": "What traffic sign does this cycleway have?", + "nl": "Welk verkeersbord heeft dit fietspad?" + }, + "condition": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "mappings": [ + { + "if": "traffic_sign=BE:D7", + "then": { + "en": "Compulsory cycleway ", + "nl": "Verplicht fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "bicycle=designated", + "mofa=designated", + "moped=yes", + "speed_pedelec=yes" + ] + }, + { + "if": "traffic_sign~BE:D7;.*", + "then": { + "en": "Compulsory cycleway (with supplementary sign)
", + "nl": "Verplicht fietspad (met onderbord)
" + }, + "hideInAnswer": true + }, + { + "if": "traffic_sign=BE:D9", + "then": { + "en": "Segregated foot/cycleway ", + "nl": "Afgescheiden voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "foot=designated", + "bicycle=designated", + "mofa=designated", + "moped=no", + "speed_pedelec=no", + "segregated=yes" + ] + }, + { + "if": "traffic_sign=BE:D10", + "then": { + "en": "Unsegregated foot/cycleway ", + "nl": "Gedeeld voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "foot=designated", + "bicycle=designated", + "mofa=designated", + "moped=no", + "speed_pedelec=no", + "segregated=no" + ] + }, + { + "if": "traffic_sign=none", + "then": { + "en": "No traffic sign present", + "nl": "Geen verkeersbord aanwezig" + } + } + ] + }, + { + "id": "cycleway-traffic-signs-supplementary", + "question": { + "en": "Does the traffic sign D7 () have a supplementary sign?", + "nl": "Heeft het verkeersbord D7 () een onderbord?" + }, + "condition": { + "or": [ + "cycleway:traffic_sign=BE:D7", + "cycleway:traffic_sign~BE:D7;.*" + ] + }, + "mappings": [ + { + "if": "cycleway:traffic_sign=BE:D7;BE:M6", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M13", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:speed_pedelec=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M14", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated", + "cycleway:speed_pedelec=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M7", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=no" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M15", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:speed_pedelec=no" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M16", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated", + "cycleway:speed_pedelec=no" + ] + }, + { + "if": "cycleway:traffic_sign:supplementary=none", + "then": { + "en": "No supplementary traffic sign present", + "nl": "Geen onderbord aanwezig" + } + } + ] + }, + { + "id": "cycleway-traffic-signs-D7-supplementary", + "question": { + "en": "Does the traffic sign D7 () have a supplementary sign?", + "nl": "Heeft het verkeersbord D7 () een onderbord?" + }, + "condition": { + "or": [ + "traffic_sign=BE:D7", + "traffic_sign~BE:D7;.*" + ] + }, + "mappings": [ + { + "if": "traffic_sign=BE:D7;BE:M6", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M13", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "speed_pedelec=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M14", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated", + "speed_pedelec=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M7", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=no" + ] + }, + { + "if": ":traffic_sign=BE:D7;BE:M15", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "speed_pedelec=no" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M16", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated", + "speed_pedelec=no" + ] + }, + { + "if": "traffic_sign:supplementary=none", + "then": { + "en": "No supplementary traffic sign present", + "nl": "Geen onderbord aanwezig" + } + } + ] + }, + { + "render": { + "en": "The buffer besides this cycleway is {cycleway:buffer} m", + "nl": "De schrikafstand van dit fietspad is {cycleway:buffer} m" + }, + "question": { + "en": "How wide is the gap between the cycleway and the road?", + "nl": "Hoe breed is de ruimte tussen het fietspad en de weg?" + }, + "condition": { + "or": [ + "cycleway=track", + "cycleway=lane" + ] + }, + "freeform": { + "key": "cycleway:buffer", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + }, + "id": "cycleways_and_roads-cycleway:buffer" + }, + { + "id": "cyclelan-segregation", + "question": { + "en": "How is this cycleway separated from the road?", + "nl": "Hoe is dit fietspad gescheiden van de weg?" + }, + "condition": { + "or": [ + "cycleway=track", + "cycleway=lane" + ] + }, + "mappings": [ + { + "if": "cycleway:separation=dashed_line", + "then": { + "en": "This cycleway is separated by a dashed line", + "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + } + }, + { + "if": "cycleway:separation=solid_line", + "then": { + "en": "This cycleway is separated by a solid line", + "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + } + }, + { + "if": "cycleway:separation=parking_lane", + "then": { + "en": "This cycleway is separated by a parking lane", + "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" + } + }, + { + "if": "cycleway:separation=kerb", + "then": { + "en": "This cycleway is separated by a kerb", + "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + } + ] + }, + { + "id": "cycleway-segregation", + "question": { + "en": "How is this cycleway separated from the road?", + "nl": "Hoe is dit fietspad gescheiden van de weg?" + }, + "condition": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "mappings": [ + { + "if": "separation=dashed_line", + "then": { + "en": "This cycleway is separated by a dashed line", + "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + } + }, + { + "if": "separation=solid_line", + "then": { + "en": "This cycleway is separated by a solid line", + "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + } + }, + { + "if": "separation=parking_lane", + "then": { + "en": "This cycleway is separated by a parking lane", + "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" + } + }, + { + "if": "separation=kerb", + "then": { + "en": "This cycleway is separated by a kerb", + "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + } + ] + } + ], + "icon": { + "render": "./assets/themes/cycle_infra/bicycleway.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "rgba(170, 170, 170, 0.7)", + "mappings": [ + { + "if": "highway=cycleway", + "then": "rgba(0, 189, 141, 0.7)" + }, + { + "if": "highway=path", + "then": "rgba(204, 74, 207, 0.7)" + }, + { + "if": "cycleway=track", + "then": "rgba(113, 3, 200, 0.7)" + }, + { + "if": "cycleway=shared_lane", + "then": "rgba(74, 59, 247, 0.7)" + }, + { + "if": "cycleway=lane", + "then": "rgba(254, 155, 6, 0.9)" + }, + { + "if": "cyclestreet=yes", + "then": "rgba(57, 159, 191, 0.7)" + } + ] + }, + "dashArray": { + "render": "", + "mappings": [ + { + "if": { + "or": [ + "oneway=yes", + { + "or": [ + "highway=cycleway", + "highway=path" + ] + } + ] + }, + "then": "" + }, + { + "if": "cycleway=track", + "then": "" + }, + { + "if": "cycleway=shared_lane", + "then": "15 30" + }, + { + "if": "cycleway=lane", + "then": "25 15 15 15 25" + }, + { + "if": "cyclestreet=yes", + "then": "" + } + ] + } } \ No newline at end of file diff --git a/assets/layers/defibrillator/defibrillator.json b/assets/layers/defibrillator/defibrillator.json index edf46f6b9..639020383 100644 --- a/assets/layers/defibrillator/defibrillator.json +++ b/assets/layers/defibrillator/defibrillator.json @@ -1,529 +1,543 @@ { - "id": "defibrillator", - "name": { - "en": "Defibrillators", - "ca": "Desfibril·ladors", - "es": "Desfibriladores", - "fr": "Défibrillateurs", - "nl": "Defibrillatoren", - "de": "Defibrillatoren", - "it": "Defibrillatori", - "ru": "Дефибрилляторы" - }, - "source": { - "osmTags": "emergency=defibrillator" - }, - "calculatedTags": [ - "_days_since_last_survey=Math.floor(new Date() - new Date(feat.properties['survey:date'])/(1000*60*60*24))", - "_recently_surveyed=Number(feat.properties._days_since_last_survey) <= 90" - ], - "minzoom": 12, - "title": { - "render": { - "en": "Defibrillator", - "ca": "Desfibril·lador", - "es": "Desfibrilador", - "fr": "Défibrillateur", - "nl": "Defibrillator", - "de": "Defibrillator", - "it": "Defibrillatore", - "ru": "Дефибриллятор" - } - }, - "icon": { - "render": "./assets/themes/aed/aed.svg", - "mappings": [ - { - "if": "_recently_surveyed=true", - "then": { - "en": "./assets/layers/defibrillator/aed_checked.svg", - "ru": "./assets/layers/defibrillator/aed_checked.svg", - "it": "./assets/layers/defibrillator/aed_checked.svg", - "fr": "./assets/layers/defibrillator/aed_checked.svg" + "id": "defibrillator", + "name": { + "en": "Defibrillators", + "ca": "Desfibril·ladors", + "es": "Desfibriladores", + "fr": "Défibrillateurs", + "nl": "Defibrillatoren", + "de": "Defibrillatoren", + "it": "Defibrillatori", + "ru": "Дефибрилляторы" + }, + "source": { + "osmTags": "emergency=defibrillator" + }, + "calculatedTags": [ + "_days_since_last_survey=Math.floor(new Date() - new Date(feat.properties['survey:date'])/(1000*60*60*24))", + "_recently_surveyed=Number(feat.properties._days_since_last_survey) <= 90" + ], + "minzoom": 12, + "title": { + "render": { + "en": "Defibrillator", + "ca": "Desfibril·lador", + "es": "Desfibrilador", + "fr": "Défibrillateur", + "nl": "Defibrillator", + "de": "Defibrillator", + "it": "Defibrillatore", + "ru": "Дефибриллятор" + } + }, + "icon": { + "render": "./assets/themes/aed/aed.svg", + "mappings": [ + { + "if": "_recently_surveyed=true", + "then": { + "en": "./assets/layers/defibrillator/aed_checked.svg", + "ru": "./assets/layers/defibrillator/aed_checked.svg", + "it": "./assets/layers/defibrillator/aed_checked.svg", + "fr": "./assets/layers/defibrillator/aed_checked.svg" + } + } + ] + }, + "color": "#0000ff", + "presets": [ + { + "title": { + "en": "Defibrillator", + "ca": "Desfibril·lador", + "es": "Desfibrilador", + "fr": "Défibrillateur", + "nl": "Defibrillator", + "de": "Defibrillator", + "it": "Defibrillatore", + "ru": "Дефибриллятор" + }, + "tags": [ + "emergency=defibrillator" + ], + "preciseInput": { + "preferredBackground": "map" + } + } + ], + "tagRenderings": [ + "images", + { + "id": "defibrillator-indoors", + "question": { + "en": "Is this defibrillator located indoors?", + "ca": "Està el desfibril·lador a l'interior?", + "es": "¿Esté el desfibrilador en interior?", + "fr": "Ce défibrillateur est-il disposé en intérieur ?", + "nl": "Hangt deze defibrillator binnen of buiten?", + "de": "Befindet sich dieser Defibrillator im Gebäude?", + "it": "Questo defibrillatore si trova all’interno?" + }, + "mappings": [ + { + "if": "indoor=yes", + "then": { + "en": "This defibrillator is located indoors", + "ca": "Aquest desfibril·lador està a l'interior", + "es": "Este desfibrilador está en interior", + "fr": "Ce défibrillateur est en intérieur (dans un batiment)", + "nl": "Deze defibrillator bevindt zich in een gebouw", + "de": "Dieser Defibrillator befindet sich im Gebäude", + "it": "Questo defibrillatore si trova all’interno" + } + }, + { + "if": "indoor=no", + "then": { + "en": "This defibrillator is located outdoors", + "ca": "Aquest desfibril·lador està a l'exterior", + "es": "Este desfibrilador está en exterior", + "fr": "Ce défibrillateur est situé en extérieur", + "nl": "Deze defibrillator hangt buiten", + "de": "Dieser Defibrillator befindet sich im Freien", + "it": "Questo defibrillatore si trova all’esterno" + } + } + ] + }, + { + "question": { + "en": "Is this defibrillator freely accessible?", + "ca": "Està el desfibril·lador accessible lliurement?", + "es": "¿Está el desfibrilador accesible libremente?", + "fr": "Ce défibrillateur est-il librement accessible ?", + "nl": "Is deze defibrillator vrij toegankelijk?", + "de": "Ist dieser Defibrillator frei zugänglich?", + "it": "Questo defibrillatore è liberamente accessibile?" + }, + "render": { + "en": "Access is {access}", + "ca": "L'accés és {access}", + "es": "El acceso es {access}", + "fr": "{access} accessible", + "nl": "Toegankelijkheid is {access}", + "de": "Zugang ist {access}", + "it": "Accesso è {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform field used for access - doublecheck the value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Publicly accessible", + "ca": "Accés lliure", + "es": "Acceso libre", + "fr": "Librement accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "it": "Pubblicamente accessibile", + "ru": "Общедоступный" + } + }, + { + "if": "access=public", + "then": { + "en": "Publicly accessible", + "ca": "Publicament accessible", + "es": "Publicament accesible", + "fr": "Librement accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "it": "Pubblicamente accessibile", + "ru": "Общедоступный" + }, + "hideInAnswer": true + }, + { + "if": "access=customers", + "then": { + "en": "Only accessible to customers", + "ca": "Només accessible a clients", + "es": "Sólo accesible a clientes", + "fr": "Réservé aux clients du lieu", + "nl": "Enkel toegankelijk voor klanten", + "de": "Nur für Kunden zugänglich", + "it": "Accessibile solo ai clienti", + "ru": "Доступно только для клиентов" + } + }, + { + "if": "access=private", + "then": { + "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", + "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", + "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", + "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", + "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personeel, de eigenaar, ...)", + "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)", + "it": "Non accessibile al pubblico (ad esempio riservato al personale, ai proprietari, etc.)" + } + }, + { + "if": "access=no", + "then": { + "en": "Not accessible, possibly only for professional use", + "nl": "Niet toegankelijk, mogelijk enkel voor professionals", + "fr": "Pas accessible, peut-être uniquement à usage professionnel", + "it": "Non accessibile, potrebbe essere solo per uso professionale" + } + } + ], + "id": "defibrillator-access" + }, + { + "render": { + "en": "There is no info about the type of device", + "nl": "Er is geen info over het soort toestel", + "fr": "Il n'y a pas d'information sur le type de dispositif", + "it": "Non vi sono informazioni riguardanti il tipo di questo dispositivo", + "de": "Es gibt keine Informationen über den Gerätetyp" + }, + "question": { + "en": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", + "nl": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", + "fr": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", + "it": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?" + }, + "freeform": { + "key": "defibrillator" + }, + "condition": { + "and": [ + "access=no" + ] + }, + "mappings": [ + { + "if": "defibrillator=manual", + "then": { + "en": "This is a manual defibrillator for professionals", + "nl": "Dit is een manueel toestel enkel voor professionals", + "fr": "C'est un défibrillateur manuel pour professionnel", + "it": "Questo è un defibrillatore manuale per professionisti", + "de": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" + } + }, + { + "if": "defibrillator=automatic", + "then": { + "en": "This is a normal automatic defibrillator", + "nl": "Dit is een gewone automatische defibrillator", + "fr": "C'est un défibrillateur automatique manuel", + "it": "È un normale defibrillatore automatico", + "ru": "Это обычный автоматический дефибриллятор" + } + } + ], + "id": "defibrillator-defibrillator" + }, + { + "question": { + "en": "On which floor is this defibrillator located?", + "ca": "A quina planta està el desfibril·lador localitzat?", + "es": "¿En qué planta se encuentra el defibrilador localizado?", + "fr": "À quel étage est situé ce défibrillateur ?", + "nl": "Op welke verdieping bevindt deze defibrillator zich?", + "de": "In welchem Stockwerk befindet sich dieser Defibrillator?", + "it": "A che piano si trova questo defibrillatore?" + }, + "condition": { + "and": [ + "indoor=yes" + ] + }, + "freeform": { + "key": "level", + "type": "int" + }, + "render": { + "en": "This defibrillator is on floor {level}", + "ca": "Aquest desfibril·lador és a la planta {level}", + "es": "El desfibrilador se encuentra en la planta {level}", + "fr": "Ce défibrillateur est à l'étage {level}", + "nl": "De defibrillator bevindt zicht op verdieping {level}", + "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk", + "it": "Questo defibrillatore è al piano {level}" + }, + "mappings": [ + { + "if": "level=0", + "then": { + "en": "This defibrillator is on the ground floor", + "nl": "Deze defibrillator bevindt zich gelijkvloers", + "fr": "Ce défibrillateur est au rez-de-chaussée", + "it": "Questo defibrillatore è al pian terreno", + "de": "Dieser Defibrillator befindet sich im Erdgeschoss" + } + }, + { + "if": "level=1", + "then": { + "en": "This defibrillator is on the first floor", + "nl": "Deze defibrillator is op de eerste verdieping", + "fr": "Ce défibrillateur est au premier étage", + "it": "Questo defibrillatore è al primo piano", + "de": "Dieser Defibrillator befindet sich in der ersten Etage" + } + } + ], + "id": "defibrillator-level" + }, + { + "render": { + "nl": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}", + "en": "Extra information about the location (in the local languagel):
{defibrillator:location}", + "fr": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}", + "de": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in the local language)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", + "it": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location" + }, + "id": "defibrillator-defibrillator:location" + }, + { + "render": { + "nl": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}", + "en": "Extra information about the location (in English):
{defibrillator:location:en}", + "fr": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}", + "de": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in English)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", + "it": "Indica più precisamente dove si trova il defibrillatore (in inglese)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location:en" + }, + "id": "defibrillator-defibrillator:location:en" + }, + { + "render": { + "nl": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}", + "en": "Extra information about the location (in French):
{defibrillator:location:fr}", + "fr": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}", + "de": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in French)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", + "it": "Indica più precisamente dove si trova il defibrillatore (in francese)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location:fr" + }, + "id": "defibrillator-defibrillator:location:fr" + }, + "wheelchair-access", + { + "render": { + "nl": "Officieel identificatienummer van het toestel: {ref}", + "en": "Official identification number of the device: {ref}", + "fr": "Numéro d'identification officiel de ce dispositif : {ref}", + "it": "Numero identificativo ufficiale di questo dispositivo:{ref}", + "de": "Offizielle Identifikationsnummer des Geräts: {ref}" + }, + "question": { + "en": "What is the official identification number of the device? (if visible on device)", + "nl": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", + "fr": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", + "it": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", + "de": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)" + }, + "freeform": { + "type": "text", + "key": "ref" + }, + "id": "defibrillator-ref" + }, + { + "render": { + "en": "Email for questions about this defibrillator: {email}", + "nl": "Email voor vragen over deze defibrillator: {email}", + "fr": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}", + "it": "Indirizzo email per le domande su questo defibrillatore:{email}", + "de": "E-Mail für Fragen zu diesem Defibrillator: {email}" + }, + "question": { + "en": "What is the email for questions about this defibrillator?", + "nl": "Wat is het email-adres voor vragen over deze defibrillator", + "fr": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", + "it": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", + "de": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "id": "defibrillator-email" + }, + { + "render": { + "en": "Telephone for questions about this defibrillator: {phone}", + "fr": "Numéro de téléphone pour questions sur le défibrillateur : {phone}", + "nl": "Telefoonnummer voor vragen over deze defibrillator: {phone}", + "it": "Numero di telefono per le domande su questo defibrillatore:{phone}", + "de": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" + }, + "question": { + "en": "What is the phone number for questions about this defibrillator?", + "fr": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", + "nl": "Wat is het telefoonnummer voor vragen over deze defibrillator", + "it": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", + "de": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "defibrillator-phone" + }, + { + "render": { + "en": "{opening_hours_table(opening_hours)}", + "nl": "{opening_hours_table(opening_hours)}", + "fr": "{opening_hours_table(opening_hours)}", + "it": "{opening_hours_table(opening_hours)}", + "ru": "{opening_hours_table(opening_hours)}" + }, + "question": { + "en": "At what times is this defibrillator available?", + "nl": "Wanneer is deze defibrillator beschikbaar?", + "fr": "À quels horaires ce défibrillateur est-il accessible ?", + "it": "In quali orari è disponibile questo defibrillatore?", + "ru": "В какое время доступен этот дефибриллятор?", + "de": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" + }, + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "en": "24/7 opened (including holidays)", + "nl": "24/7 open (inclusief feestdagen)", + "fr": "Ouvert 24/7 (jours feriés inclus)", + "it": "Aperto 24/7 (festivi inclusi)", + "de": "24/7 geöffnet (auch an Feiertagen)" + } + } + ], + "id": "defibrillator-opening_hours" + }, + { + "render": { + "en": "Additional information: {description}", + "nl": "Aanvullende info: {description}", + "fr": "Informations supplémentaires : {description}", + "it": "Informazioni supplementari: {description}", + "ru": "Дополнительная информация: {description}", + "de": "Zusätzliche Informationen: {description}", + "id": "Informasi tambahan: {description}" + }, + "question": { + "en": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", + "nl": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", + "fr": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", + "it": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", + "de": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)" + }, + "freeform": { + "key": "description", + "type": "text" + }, + "id": "defibrillator-description" + }, + { + "question": { + "en": "When was this defibrillator last surveyed?", + "nl": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", + "fr": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", + "it": "Quando è stato verificato per l’ultima volta questo defibrillatore?", + "de": "Wann wurde dieser Defibrillator zuletzt überprüft?" + }, + "render": { + "en": "This defibrillator was last surveyed on {survey:date}", + "nl": "Deze defibrillator is nagekeken in OSM op {survey:date}", + "fr": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}", + "it": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}", + "de": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" + }, + "freeform": { + "key": "survey:date", + "type": "date" + }, + "mappings": [ + { + "if": "survey:date:={_now:date}", + "then": { + "en": "Checked today!", + "nl": "Vandaag nagekeken!", + "fr": "Vérifié aujourd'hui !", + "it": "Verificato oggi!", + "ru": "Проверено сегодня!", + "de": "Heute überprüft!" + } + } + ], + "id": "defibrillator-survey:date" + }, + { + "render": { + "en": "Extra information for OpenStreetMap experts: {fixme}", + "nl": "Extra informatie voor OpenStreetMap experts: {fixme}", + "fr": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}", + "it": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}", + "de": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}", + "ru": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" + }, + "question": { + "en": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", + "nl": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", + "fr": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", + "it": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", + "de": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)" + }, + "freeform": { + "key": "fixme", + "type": "text" + }, + "id": "defibrillator-fixme" } - } ] - }, - "color": "#0000ff", - "presets": [ - { - "title": { - "en": "Defibrillator", - "ca": "Desfibril·lador", - "es": "Desfibrilador", - "fr": "Défibrillateur", - "nl": "Defibrillator", - "de": "Defibrillator", - "it": "Defibrillatore", - "ru": "Дефибриллятор" - }, - "tags": [ - "emergency=defibrillator" - ], - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Is this defibrillator located indoors?", - "ca": "Està el desfibril·lador a l'interior?", - "es": "¿Esté el desfibrilador en interior?", - "fr": "Ce défibrillateur est-il disposé en intérieur ?", - "nl": "Hangt deze defibrillator binnen of buiten?", - "de": "Befindet sich dieser Defibrillator im Gebäude?", - "it": "Questo defibrillatore si trova all’interno?" - }, - "mappings": [ - { - "if": "indoor=yes", - "then": { - "en": "This defibrillator is located indoors", - "ca": "Aquest desfibril·lador està a l'interior", - "es": "Este desfibrilador está en interior", - "fr": "Ce défibrillateur est en intérieur (dans un batiment)", - "nl": "Deze defibrillator bevindt zich in een gebouw", - "de": "Dieser Defibrillator befindet sich im Gebäude", - "it": "Questo defibrillatore si trova all’interno" - } - }, - { - "if": "indoor=no", - "then": { - "en": "This defibrillator is located outdoors", - "ca": "Aquest desfibril·lador està a l'exterior", - "es": "Este desfibrilador está en exterior", - "fr": "Ce défibrillateur est situé en extérieur", - "nl": "Deze defibrillator hangt buiten", - "de": "Dieser Defibrillator befindet sich im Freien", - "it": "Questo defibrillatore si trova all’esterno" - } - } - ] - }, - { - "question": { - "en": "Is this defibrillator freely accessible?", - "ca": "Està el desfibril·lador accessible lliurement?", - "es": "¿Está el desfibrilador accesible libremente?", - "fr": "Ce défibrillateur est-il librement accessible ?", - "nl": "Is deze defibrillator vrij toegankelijk?", - "de": "Ist dieser Defibrillator frei zugänglich?", - "it": "Questo defibrillatore è liberamente accessibile?" - }, - "render": { - "en": "Access is {access}", - "ca": "L'accés és {access}", - "es": "El acceso es {access}", - "fr": "{access} accessible", - "nl": "Toegankelijkheid is {access}", - "de": "Zugang ist {access}", - "it": "Accesso è {access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform field used for access - doublecheck the value" - ] - }, - "mappings": [ - { - "if": "access=yes", - "then": { - "en": "Publicly accessible", - "ca": "Accés lliure", - "es": "Acceso libre", - "fr": "Librement accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "it": "Pubblicamente accessibile", - "ru": "Общедоступный" - } - }, - { - "if": "access=public", - "then": { - "en": "Publicly accessible", - "ca": "Publicament accessible", - "es": "Publicament accesible", - "fr": "Librement accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "it": "Pubblicamente accessibile", - "ru": "Общедоступный" - }, - "hideInAnswer": true - }, - { - "if": "access=customers", - "then": { - "en": "Only accessible to customers", - "ca": "Només accessible a clients", - "es": "Sólo accesible a clientes", - "fr": "Réservé aux clients du lieu", - "nl": "Enkel toegankelijk voor klanten", - "de": "Nur für Kunden zugänglich", - "it": "Accessibile solo ai clienti", - "ru": "Доступно только для клиентов" - } - }, - { - "if": "access=private", - "then": { - "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", - "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", - "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", - "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", - "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personeel, de eigenaar, ...)", - "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)", - "it": "Non accessibile al pubblico (ad esempio riservato al personale, ai proprietari, etc.)" - } - }, - { - "if": "access=no", - "then": { - "en": "Not accessible, possibly only for professional use", - "nl": "Niet toegankelijk, mogelijk enkel voor professionals", - "fr": "Pas accessible, peut-être uniquement à usage professionnel", - "it": "Non accessibile, potrebbe essere solo per uso professionale" - } - } - ] - }, - { - "render": { - "en": "There is no info about the type of device", - "nl": "Er is geen info over het soort toestel", - "fr": "Il n'y a pas d'information sur le type de dispositif", - "it": "Non vi sono informazioni riguardanti il tipo di questo dispositivo", - "de": "Es gibt keine Informationen über den Gerätetyp" - }, - "question": { - "en": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", - "nl": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", - "fr": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", - "it": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?" - }, - "freeform": { - "key": "defibrillator" - }, - "condition": { - "and": [ - "access=no" - ] - }, - "mappings": [ - { - "if": "defibrillator=manual", - "then": { - "en": "This is a manual defibrillator for professionals", - "nl": "Dit is een manueel toestel enkel voor professionals", - "fr": "C'est un défibrillateur manuel pour professionnel", - "it": "Questo è un defibrillatore manuale per professionisti", - "de": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" - } - }, - { - "if": "defibrillator=automatic", - "then": { - "en": "This is a normal automatic defibrillator", - "nl": "Dit is een gewone automatische defibrillator", - "fr": "C'est un défibrillateur automatique manuel", - "it": "È un normale defibrillatore automatico", - "ru": "Это обычный автоматический дефибриллятор" - } - } - ] - }, - { - "question": { - "en": "On which floor is this defibrillator located?", - "ca": "A quina planta està el desfibril·lador localitzat?", - "es": "¿En qué planta se encuentra el defibrilador localizado?", - "fr": "À quel étage est situé ce défibrillateur ?", - "nl": "Op welke verdieping bevindt deze defibrillator zich?", - "de": "In welchem Stockwerk befindet sich dieser Defibrillator?", - "it": "A che piano si trova questo defibrillatore?" - }, - "condition": { - "and": [ - "indoor=yes" - ] - }, - "freeform": { - "key": "level", - "type": "int" - }, - "render": { - "en": "This defibrillator is on floor {level}", - "ca": "Aquest desfibril·lador és a la planta {level}", - "es": "El desfibrilador se encuentra en la planta {level}", - "fr": "Ce défibrillateur est à l'étage {level}", - "nl": "De defibrillator bevindt zicht op verdieping {level}", - "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk", - "it": "Questo defibrillatore è al piano {level}" - }, - "mappings": [ - { - "if": "level=0", - "then": { - "en": "This defibrillator is on the ground floor", - "nl": "Deze defibrillator bevindt zich gelijkvloers", - "fr": "Ce défibrillateur est au rez-de-chaussée", - "it": "Questo defibrillatore è al pian terreno", - "de": "Dieser Defibrillator befindet sich im Erdgeschoss" - } - }, - { - "if": "level=1", - "then": { - "en": "This defibrillator is on the first floor", - "nl": "Deze defibrillator is op de eerste verdieping", - "fr": "Ce défibrillateur est au premier étage", - "it": "Questo defibrillatore è al primo piano", - "de": "Dieser Defibrillator befindet sich in der ersten Etage" - } - } - ] - }, - { - "render": { - "nl": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}", - "en": "Extra information about the location (in the local languagel):
{defibrillator:location}", - "fr": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}", - "de": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in the local language)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", - "it": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location" - } - }, - { - "render": { - "nl": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}", - "en": "Extra information about the location (in English):
{defibrillator:location:en}", - "fr": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}", - "de": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in English)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", - "it": "Indica più precisamente dove si trova il defibrillatore (in inglese)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location:en" - } - }, - { - "render": { - "nl": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}", - "en": "Extra information about the location (in French):
{defibrillator:location:fr}", - "fr": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}", - "de": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in French)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", - "it": "Indica più precisamente dove si trova il defibrillatore (in francese)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location:fr" - } - }, - "wheelchair-access", - { - "render": { - "nl": "Officieel identificatienummer van het toestel: {ref}", - "en": "Official identification number of the device: {ref}", - "fr": "Numéro d'identification officiel de ce dispositif : {ref}", - "it": "Numero identificativo ufficiale di questo dispositivo:{ref}", - "de": "Offizielle Identifikationsnummer des Geräts: {ref}" - }, - "question": { - "en": "What is the official identification number of the device? (if visible on device)", - "nl": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", - "fr": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", - "it": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", - "de": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)" - }, - "freeform": { - "type": "text", - "key": "ref" - } - }, - { - "render": { - "en": "Email for questions about this defibrillator: {email}", - "nl": "Email voor vragen over deze defibrillator: {email}", - "fr": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}", - "it": "Indirizzo email per le domande su questo defibrillatore:{email}", - "de": "E-Mail für Fragen zu diesem Defibrillator: {email}" - }, - "question": { - "en": "What is the email for questions about this defibrillator?", - "nl": "Wat is het email-adres voor vragen over deze defibrillator", - "fr": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", - "it": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", - "de": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "render": { - "en": "Telephone for questions about this defibrillator: {phone}", - "fr": "Numéro de téléphone pour questions sur le défibrillateur : {phone}", - "nl": "Telefoonnummer voor vragen over deze defibrillator: {phone}", - "it": "Numero di telefono per le domande su questo defibrillatore:{phone}", - "de": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" - }, - "question": { - "en": "What is the phone number for questions about this defibrillator?", - "fr": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", - "nl": "Wat is het telefoonnummer voor vragen over deze defibrillator", - "it": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", - "de": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "render": { - "en": "{opening_hours_table(opening_hours)}", - "nl": "{opening_hours_table(opening_hours)}", - "fr": "{opening_hours_table(opening_hours)}", - "it": "{opening_hours_table(opening_hours)}", - "ru": "{opening_hours_table(opening_hours)}" - }, - "question": { - "en": "At what times is this defibrillator available?", - "nl": "Wanneer is deze defibrillator beschikbaar?", - "fr": "À quels horaires ce défibrillateur est-il accessible ?", - "it": "In quali orari è disponibile questo defibrillatore?", - "ru": "В какое время доступен этот дефибриллятор?", - "de": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" - }, - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "en": "24/7 opened (including holidays)", - "nl": "24/7 open (inclusief feestdagen)", - "fr": "Ouvert 24/7 (jours feriés inclus)", - "it": "Aperto 24/7 (festivi inclusi)", - "de": "24/7 geöffnet (auch an Feiertagen)" - } - } - ] - }, - { - "render": { - "en": "Additional information: {description}", - "nl": "Aanvullende info: {description}", - "fr": "Informations supplémentaires : {description}", - "it": "Informazioni supplementari: {description}", - "ru": "Дополнительная информация: {description}", - "de": "Zusätzliche Informationen: {description}", - "id": "Informasi tambahan: {description}" - }, - "question": { - "en": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", - "nl": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", - "fr": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", - "it": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", - "de": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)" - }, - "freeform": { - "key": "description", - "type": "text" - } - }, - { - "question": { - "en": "When was this defibrillator last surveyed?", - "nl": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", - "fr": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", - "it": "Quando è stato verificato per l’ultima volta questo defibrillatore?", - "de": "Wann wurde dieser Defibrillator zuletzt überprüft?" - }, - "render": { - "en": "This defibrillator was last surveyed on {survey:date}", - "nl": "Deze defibrillator is nagekeken in OSM op {survey:date}", - "fr": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}", - "it": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}", - "de": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": { - "en": "Checked today!", - "nl": "Vandaag nagekeken!", - "fr": "Vérifié aujourd'hui !", - "it": "Verificato oggi!", - "ru": "Проверено сегодня!", - "de": "Heute überprüft!" - } - } - ] - }, - { - "render": { - "en": "Extra information for OpenStreetMap experts: {fixme}", - "nl": "Extra informatie voor OpenStreetMap experts: {fixme}", - "fr": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}", - "it": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}", - "de": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}", - "ru": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" - }, - "question": { - "en": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", - "nl": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", - "fr": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", - "it": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", - "de": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)" - }, - "freeform": { - "key": "fixme", - "type": "text" - } - } - ] } \ No newline at end of file diff --git a/assets/layers/direction/direction.json b/assets/layers/direction/direction.json index fddfd64f3..4d3fd684d 100644 --- a/assets/layers/direction/direction.json +++ b/assets/layers/direction/direction.json @@ -1,47 +1,47 @@ { - "id": "direction", - "name": { - "en": "Direction visualization", - "nl": "Richtingsvisualisatie", - "fr": "Visualisation de la direction", - "it": "Visualizzazione della direzione", - "ru": "Визуализация направления" - }, - "minzoom": 16, - "source": { - "osmTags": { - "or": [ - "camera:direction~*", - "direction~*" - ] - } - }, - "doNotDownload": true, - "passAllFeatures": true, - "title": null, - "description": { - "en": "This layer visualizes directions", - "nl": "Deze laag toont de oriëntatie van een object", - "fr": "Cette couche visualise les directions", - "it": "Questo livello visualizza le direzioni" - }, - "tagRenderings": [], - "icon": { - "render": "direction_gradient:var(--catch-detail-color)", - "#": "For some weird reason, showing the icon in the layer control panel breaks the svg-gradient (because the svg gradient has a global color or smthng) - so we use a different icon without gradient", - "mappings": [ - { - "if": "id=node/-1", - "then": "direction:var(--catch-detail-color)" - } - ] - }, - "rotation": { - "render": "{_direction:numerical}deg" - }, - "iconSize": "200,200,center", - "color": "--catch-detail-color", - "stroke": "0", - "presets": [], - "wayHandling": 2 + "id": "direction", + "name": { + "en": "Direction visualization", + "nl": "Richtingsvisualisatie", + "fr": "Visualisation de la direction", + "it": "Visualizzazione della direzione", + "ru": "Визуализация направления" + }, + "minzoom": 16, + "source": { + "osmTags": { + "or": [ + "camera:direction~*", + "direction~*" + ] + } + }, + "doNotDownload": true, + "passAllFeatures": true, + "title": null, + "description": { + "en": "This layer visualizes directions", + "nl": "Deze laag toont de oriëntatie van een object", + "fr": "Cette couche visualise les directions", + "it": "Questo livello visualizza le direzioni" + }, + "tagRenderings": [], + "icon": { + "render": "direction_gradient:var(--catch-detail-color)", + "#": "For some weird reason, showing the icon in the layer control panel breaks the svg-gradient (because the svg gradient has a global color or smthng) - so we use a different icon without gradient", + "mappings": [ + { + "if": "id=node/-1", + "then": "direction:var(--catch-detail-color)" + } + ] + }, + "rotation": { + "render": "{_direction:numerical}deg" + }, + "iconSize": "200,200,center", + "color": "--catch-detail-color", + "stroke": "0", + "presets": [], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 3645da855..43af3910c 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -1,61 +1,6 @@ { - "id": "drinking_water", - "name": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - }, - "title": { - "render": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - } - }, - "icon": { - "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" - }, - "iconOverlays": [ - { - "if": { - "or": [ - "operational_status=broken", - "operational_status=closed" - ] - }, - "then": "close:#c33", - "badge": true - } - ], - "iconSize": "40,40,bottom", - "source": { - "osmTags": { - "and": [ - "amenity=drinking_water", - "access!=permissive", - "access!=private" - ] - } - }, - "calculatedTags": [ - "_closest_other_drinking_water_id=feat.closest('drinking_water')?.id", - "_closest_other_drinking_water_distance=Math.floor(feat.distanceTo(feat.closest('drinking_water')).distance * 1000)" - ], - "minzoom": 13, - "wayHandling": 1, - "presets": [ - { - "title": { + "id": "drinking_water", + "name": { "en": "Drinking water", "nl": "Drinkbaar water", "fr": "Eau potable", @@ -64,105 +9,162 @@ "it": "Acqua potabile", "ru": "Питьевая вода", "id": "Air minum" - }, - "tags": [ - "amenity=drinking_water" - ] - } - ], - "color": "#6bc4f7", - "tagRenderings": [ - "images", - { - "#": "Still in use?", - "question": { - "en": "Is this drinking water spot still operational?", - "nl": "Is deze drinkwaterkraan nog steeds werkende?", - "it": "Questo punto di acqua potabile è sempre funzionante?", - "fr": "Ce point d'eau potable est-il toujours opérationnel ?", - "de": "Ist diese Trinkwasserstelle noch in Betrieb?" - }, - "render": { - "en": "The operational status is {operational_status", - "nl": "Deze waterkraan-status is {operational_status}", - "it": "Lo stato operativo è {operational_status}", - "fr": "L'état opérationnel est {operational_status", - "de": "Der Betriebsstatus ist {operational_status" - }, - "freeform": { - "key": "operational_status" - }, - "mappings": [ - { - "if": "operational_status=", - "then": { - "en": "This drinking water works", - "nl": "Deze drinkwaterfontein werkt", - "it": "La fontanella funziona", - "fr": "Cette fontaine fonctionne" - } - }, - { - "if": "operational_status=broken", - "then": { - "en": "This drinking water is broken", - "nl": "Deze drinkwaterfontein is kapot", - "it": "La fontanella è guasta", - "fr": "Cette fontaine est cassée" - } - }, - { - "if": "operational_status=closed", - "then": { - "en": "This drinking water is closed", - "nl": "Deze drinkwaterfontein is afgesloten", - "it": "La fontanella è chiusa", - "fr": "Cette fontaine est fermée" - } - } - ] }, - { - "#": "Bottle refill", - "question": { - "en": "How easy is it to fill water bottles?", - "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", - "de": "Wie einfach ist es, Wasserflaschen zu füllen?", - "it": "Quanto è facile riempire d’acqua le bottiglie?", - "fr": "Est-il facile de remplir des bouteilles d'eau ?" - }, - "mappings": [ + "title": { + "render": { + "en": "Drinking water", + "nl": "Drinkbaar water", + "fr": "Eau potable", + "gl": "Auga potábel", + "de": "Trinkwasser", + "it": "Acqua potabile", + "ru": "Питьевая вода", + "id": "Air minum" + } + }, + "icon": { + "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" + }, + "iconOverlays": [ { - "if": "bottle=yes", - "then": { - "en": "It is easy to refill water bottles", - "nl": "Een drinkbus bijvullen gaat makkelijk", - "de": "Es ist einfach, Wasserflaschen nachzufüllen", - "it": "È facile riempire d’acqua le bottiglie", - "fr": "Il est facile de remplir les bouteilles d'eau" - } + "if": { + "or": [ + "operational_status=broken", + "operational_status=closed" + ] + }, + "then": "close:#c33", + "badge": true + } + ], + "iconSize": "40,40,bottom", + "source": { + "osmTags": { + "and": [ + "amenity=drinking_water", + "access!=permissive", + "access!=private" + ] + } + }, + "calculatedTags": [ + "_closest_other_drinking_water=feat.closestn('drinking_water', 1, undefined, 5000).map(f => ({id: f.feat.id, distance: ''+f.distance}))[0]", + "_closest_other_drinking_water_id=JSON.parse(feat.properties._closest_other_drinking_water)?.id", + "_closest_other_drinking_water_distance=Math.floor(Number(JSON.parse(feat.properties._closest_other_drinking_water)?.distance) * 1000)" + ], + "minzoom": 13, + "wayHandling": 1, + "presets": [ + { + "title": { + "en": "drinking water", + "nl": "drinkbaar water", + "fr": "eau potable", + "gl": "auga potábel", + "de": "trinkwasser", + "it": "acqua potabile", + "ru": "Питьевая вода", + "id": "air minum" + }, + "tags": [ + "amenity=drinking_water" + ] + } + ], + "color": "#6bc4f7", + "tagRenderings": [ + "images", + { + "question": { + "en": "Is this drinking water spot still operational?", + "nl": "Is deze drinkwaterkraan nog steeds werkende?", + "it": "Questo punto di acqua potabile è sempre funzionante?", + "fr": "Ce point d'eau potable est-il toujours opérationnel ?", + "de": "Ist diese Trinkwasserstelle noch in Betrieb?" + }, + "render": { + "en": "The operational status is {operational_status", + "nl": "Deze waterkraan-status is {operational_status}", + "it": "Lo stato operativo è {operational_status}", + "fr": "L'état opérationnel est {operational_status", + "de": "Der Betriebsstatus ist {operational_status" + }, + "freeform": { + "key": "operational_status" + }, + "mappings": [ + { + "if": "operational_status=", + "then": { + "en": "This drinking water works", + "nl": "Deze drinkwaterfontein werkt", + "it": "La fontanella funziona", + "fr": "Cette fontaine fonctionne" + } + }, + { + "if": "operational_status=broken", + "then": { + "en": "This drinking water is broken", + "nl": "Deze drinkwaterfontein is kapot", + "it": "La fontanella è guasta", + "fr": "Cette fontaine est cassée" + } + }, + { + "if": "operational_status=closed", + "then": { + "en": "This drinking water is closed", + "nl": "Deze drinkwaterfontein is afgesloten", + "it": "La fontanella è chiusa", + "fr": "Cette fontaine est fermée" + } + } + ], + "id": "Still in use?" }, { - "if": "bottle=no", - "then": { - "en": "Water bottles may not fit", - "nl": "Een drinkbus past moeilijk", - "de": "Wasserflaschen passen möglicherweise nicht", - "it": "Le bottiglie d’acqua potrebbero non entrare", - "fr": "Les bouteilles d'eau peuvent ne pas passer" - } + "question": { + "en": "How easy is it to fill water bottles?", + "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", + "de": "Wie einfach ist es, Wasserflaschen zu füllen?", + "it": "Quanto è facile riempire d’acqua le bottiglie?", + "fr": "Est-il facile de remplir des bouteilles d'eau ?" + }, + "mappings": [ + { + "if": "bottle=yes", + "then": { + "en": "It is easy to refill water bottles", + "nl": "Een drinkbus bijvullen gaat makkelijk", + "de": "Es ist einfach, Wasserflaschen nachzufüllen", + "it": "È facile riempire d’acqua le bottiglie", + "fr": "Il est facile de remplir les bouteilles d'eau" + } + }, + { + "if": "bottle=no", + "then": { + "en": "Water bottles may not fit", + "nl": "Een drinkbus past moeilijk", + "de": "Wasserflaschen passen möglicherweise nicht", + "it": "Le bottiglie d’acqua potrebbero non entrare", + "fr": "Les bouteilles d'eau peuvent ne pas passer" + } + } + ], + "id": "Bottle refill" + }, + { + "id": "render-closest-drinking-water", + "render": { + "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", + "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", + "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", + "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", + "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" + }, + "condition": "_closest_other_drinking_water_id~*" } - ] - }, - { - "render": { - "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", - "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", - "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", - "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", - "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" - }, - "condition": "_closest_other_drinking_water_id~*" - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index 9c5ce26fd..1bac9814d 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -1,619 +1,628 @@ { - "id": "food", - "name": { - "nl": "Eetgelegenheden", - "en": "Restaurants and fast food" - }, - "source": { - "osmTags": { - "or": [ - "amenity=fast_food", - "amenity=restaurant" - ] - } - }, - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/food/restaurant.svg", - "mappings": [ - { - "if": { - "and": [ - "amenity=fast_food", - "cuisine=friture" - ] - }, - "then": "circle:white;./assets/layers/food/fries.svg" - }, - { - "if": "amenity=fast_food", - "then": "circle:white;./assets/layers/food/fastfood.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "id": "food", + "name": { + "nl": "Eetgelegenheden", + "en": "Restaurants and fast food" }, - { - "if": { - "or": [ - "diet:vegetarian=yes", - "diet:vegan=yes" + "source": { + "osmTags": { + "or": [ + "amenity=fast_food", + "amenity=restaurant" + ] + } + }, + "minzoom": 12, + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/food/restaurant.svg", + "mappings": [ + { + "if": { + "and": [ + "amenity=fast_food", + "cuisine=friture" + ] + }, + "then": "circle:white;./assets/layers/food/fries.svg" + }, + { + "if": "amenity=fast_food", + "then": "circle:white;./assets/layers/food/fastfood.svg" + } ] - }, - "then": { - "render": "circle:white;./assets/themes/fritures/Vegetarian-mark.svg" - }, - "badge": true - } - ], - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "presets": [ - { - "title": { - "en": "restaurant", - "nl": "restaurant" - }, - "tags": [ - "amenity=restaurant" - ], - "description": { - "nl": "Een eetgegelegenheid waar je aan tafel wordt bediend", - "en": "A formal eating place with sit-down facilities selling full meals served by waiters" - }, - "preciseInput": { - "preferredBackground": "map" - } }, - { - "title": { - "en": "fastfood", - "nl": "fastfood-zaak" - }, - "tags": [ - "amenity=fast_food" - ], - "description": { - "nl": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt (of zelfs afwezig)", - "en": "A food business concentrating on fast counter-only service and take-away food" - }, - "preciseInput": { - "preferredBackground": "map" - } - }, - { - "title": { - "en": "fries shop", - "nl": "frituur" - }, - "tags": [ - "amenity=fast_food", - "cuisine=friture" - ], - "description": { - "nl": "Een fastfood-zaak waar je frieten koopt" - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "title": { - "render": { - "nl": "Eetgelegenheid" - }, - "mappings": [ - { - "if": { - "and": [ - "name~*", - "amenity=restaurant" - ] - }, - "then": { - "nl": "Restaurant {name}", - "en": "Restaurant {name}" - } - }, - { - "if": { - "and": [ - "name~*", - "amenity=fast_food" - ] - }, - "then": { - "nl": "Fastfood-zaak {name}", - "en": "Fastfood {name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "#": "Name", - "question": { - "nl": "Wat is de naam van deze eetgelegenheid?", - "en": "What is the name of this restaurant?" - }, - "render": { - "nl": "De naam van deze eetgelegeheid is {name}", - "en": "The name of this restaurant is {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Fastfood vs restaurant", - "question": { - "en": "What type of business is this?", - "nl": "Wat voor soort zaak is dit?" - }, - "mappings": [ + "iconOverlays": [ { - "if": "amenity=fast_food", - "then": { - "nl": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" - } + "if": "opening_hours~*", + "then": "isOpen", + "badge": true }, { - "if": "amenity=restaurant", - "then": { - "nl": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" - } + "if": { + "or": [ + "diet:vegetarian=yes", + "diet:vegan=yes" + ] + }, + "then": { + "render": "circle:white;./assets/themes/fritures/Vegetarian-mark.svg" + }, + "badge": true } - ] - }, - "opening_hours", - "website", - "email", - "phone", - "payment-options", - "wheelchair-access", - { - "#": "Cuisine", - "question": { - "nl": "Welk soort gerechten worden hier geserveerd?", - "en": "Which food is served here?" - }, - "render": { - "nl": "Deze plaats serveert vooral {cuisine}", - "en": "This place mostly serves {cuisine}" - }, - "freeform": { - "key": "cuisine", - "addExtraTags": [ - "fixme=Freeform tag `cuisine` used, to be doublechecked" + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } ] - }, - "mappings": [ - { - "if": "cuisine=pizza", - "then": { - "en": "This is a pizzeria", - "nl": "Dit is een pizzeria" - } - }, - { - "if": "cuisine=friture", - "then": { - "en": "This is a friture", - "nl": "Dit is een frituur" - } - }, - { - "if": "cuisine=pasta", - "then": { - "en": "Mainly serves pasta", - "nl": "Dit is een pastazaak" - } - }, - { - "if": "cuisine=kebab", - "then": { - "nl": "Dit is een kebabzaak" - } - }, - { - "if": "cuisine=sandwich", - "then": { - "nl": "Dit is een broodjeszaak" - } - }, - { - "if": "cuisine=burger", - "then": { - "nl": "Dit is een hamburgerrestaurant" - } - }, - { - "if": "cuisine=sushi", - "then": { - "nl": "Dit is een sushirestaurant" - } - }, - { - "if": "cuisine=coffee", - "then": { - "nl": "Dit is een koffiezaak" - } - }, - { - "if": "cuisine=italian", - "then": { - "nl": "Dit is een Italiaans restaurant (dat meer dan enkel pasta of pizza verkoopt)" - } - }, - { - "if": "cuisine=french", - "then": { - "nl": "Dit is een Frans restaurant" - } - }, - { - "if": "cuisine=chinese", - "then": { - "nl": "Dit is een Chinees restaurant" - } - }, - { - "if": "cuisine=greek", - "then": { - "nl": "Dit is een Grieks restaurant" - } - }, - { - "if": "cuisine=indian", - "then": { - "nl": "Dit is een Indisch restaurant" - } - }, - { - "if": "cuisine=turkish", - "then": { - "nl": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)" - } - }, - { - "if": "cuisine=thai", - "then": { - "nl": "Dit is een Thaïs restaurant" - } - } - ] }, - { - "#": "Takeaway", - "question": { - "nl": "Biedt deze zaak een afhaalmogelijkheid aan?", - "en": "Does this place offer takea-way?" - }, - "mappings": [ + "presets": [ { - "if": "takeaway=only", - "then": { - "en": "This is a take-away only business", - "nl": "Hier is enkel afhaal mogelijk" - } + "title": { + "en": "restaurant", + "nl": "restaurant" + }, + "tags": [ + "amenity=restaurant" + ], + "description": { + "nl": "Een eetgegelegenheid waar je aan tafel wordt bediend", + "en": "A formal eating place with sit-down facilities selling full meals served by waiters" + }, + "preciseInput": { + "preferredBackground": "map" + } }, { - "if": "takeaway=yes", - "then": { - "en": "Take-away is possible here", - "nl": "Eten kan hier afgehaald worden" - } + "title": { + "en": "fastfood", + "nl": "fastfood-zaak" + }, + "tags": [ + "amenity=fast_food" + ], + "description": { + "nl": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt (of zelfs afwezig)", + "en": "A food business concentrating on fast counter-only service and take-away food" + }, + "preciseInput": { + "preferredBackground": "map" + } }, { - "if": "takeaway=no", - "then": { - "en": "Take-away is not possible here", - "nl": "Hier is geen afhaalmogelijkheid" - } + "title": { + "en": "fries shop", + "nl": "frituur" + }, + "tags": [ + "amenity=fast_food", + "cuisine=friture" + ], + "description": { + "nl": "Een fastfood-zaak waar je frieten koopt" + }, + "preciseInput": { + "preferredBackground": "map" + } } - ] + ], + "title": { + "render": { + "nl": "Eetgelegenheid" + }, + "mappings": [ + { + "if": { + "and": [ + "name~*", + "amenity=restaurant" + ] + }, + "then": { + "nl": "Restaurant {name}", + "en": "Restaurant {name}" + } + }, + { + "if": { + "and": [ + "name~*", + "amenity=fast_food" + ] + }, + "then": { + "nl": "Fastfood-zaak {name}", + "en": "Fastfood {name}" + } + } + ] }, - { - "#": "Vegetarian (no friture)", - "question": { - "nl": "Heeft deze eetgelegenheid een vegetarische optie?", - "en": "Does this restaurant have a vegetarian option?" - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "diet:vegetarian=no", - "then": { - "nl": "Geen vegetarische opties beschikbaar" - } + "question": { + "nl": "Wat is de naam van deze eetgelegenheid?", + "en": "What is the name of this restaurant?" + }, + "render": { + "nl": "De naam van deze eetgelegeheid is {name}", + "en": "The name of this restaurant is {name}" + }, + "freeform": { + "key": "name" + }, + "id": "Name" }, { - "if": "diet:vegetarian=limited", - "then": { - "nl": "Beperkte vegetarische opties zijn beschikbaar" - } + "question": { + "en": "What type of business is this?", + "nl": "Wat voor soort zaak is dit?" + }, + "mappings": [ + { + "if": "amenity=fast_food", + "then": { + "nl": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" + } + }, + { + "if": "amenity=restaurant", + "then": { + "nl": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" + } + } + ], + "id": "Fastfood vs restaurant" + }, + "opening_hours", + "website", + "email", + "phone", + "payment-options", + "wheelchair-access", + { + "question": { + "nl": "Welk soort gerechten worden hier geserveerd?", + "en": "Which food is served here?" + }, + "render": { + "nl": "Deze plaats serveert vooral {cuisine}", + "en": "This place mostly serves {cuisine}" + }, + "freeform": { + "key": "cuisine", + "addExtraTags": [ + "fixme=Freeform tag `cuisine` used, to be doublechecked" + ] + }, + "mappings": [ + { + "if": "cuisine=pizza", + "then": { + "en": "This is a pizzeria", + "nl": "Dit is een pizzeria" + } + }, + { + "if": "cuisine=friture", + "then": { + "en": "This is a friture", + "nl": "Dit is een frituur" + } + }, + { + "if": "cuisine=pasta", + "then": { + "en": "Mainly serves pasta", + "nl": "Dit is een pastazaak" + } + }, + { + "if": "cuisine=kebab", + "then": { + "nl": "Dit is een kebabzaak" + } + }, + { + "if": "cuisine=sandwich", + "then": { + "nl": "Dit is een broodjeszaak" + } + }, + { + "if": "cuisine=burger", + "then": { + "nl": "Dit is een hamburgerrestaurant" + } + }, + { + "if": "cuisine=sushi", + "then": { + "nl": "Dit is een sushirestaurant" + } + }, + { + "if": "cuisine=coffee", + "then": { + "nl": "Dit is een koffiezaak" + } + }, + { + "if": "cuisine=italian", + "then": { + "nl": "Dit is een Italiaans restaurant (dat meer dan enkel pasta of pizza verkoopt)" + } + }, + { + "if": "cuisine=french", + "then": { + "nl": "Dit is een Frans restaurant" + } + }, + { + "if": "cuisine=chinese", + "then": { + "nl": "Dit is een Chinees restaurant" + } + }, + { + "if": "cuisine=greek", + "then": { + "nl": "Dit is een Grieks restaurant" + } + }, + { + "if": "cuisine=indian", + "then": { + "nl": "Dit is een Indisch restaurant" + } + }, + { + "if": "cuisine=turkish", + "then": { + "nl": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)" + } + }, + { + "if": "cuisine=thai", + "then": { + "nl": "Dit is een Thaïs restaurant" + } + } + ], + "id": "Cuisine" }, { - "if": "diet:vegetarian=yes", - "then": { - "nl": "Vegetarische opties zijn beschikbaar" - } + "question": { + "nl": "Biedt deze zaak een afhaalmogelijkheid aan?", + "en": "Does this place offer takea-way?" + }, + "mappings": [ + { + "if": "takeaway=only", + "then": { + "en": "This is a take-away only business", + "nl": "Hier is enkel afhaal mogelijk" + } + }, + { + "if": "takeaway=yes", + "then": { + "en": "Take-away is possible here", + "nl": "Eten kan hier afgehaald worden" + } + }, + { + "if": "takeaway=no", + "then": { + "en": "Take-away is not possible here", + "nl": "Hier is geen afhaalmogelijkheid" + } + } + ], + "id": "Takeaway" }, { - "if": "diet:vegetarian=only", - "then": { - "nl": "Enkel vegetarische opties zijn beschikbaar" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "#": "Vegan (no friture)", - "question": { - "nl": "Heeft deze eetgelegenheid een veganistische optie?" - }, - "mappings": [ - { - "if": "diet:vegan=no", - "then": { - "nl": "Geen veganistische opties beschikbaar" - } + "question": { + "nl": "Heeft deze eetgelegenheid een vegetarische optie?", + "en": "Does this restaurant have a vegetarian option?" + }, + "mappings": [ + { + "if": "diet:vegetarian=no", + "then": { + "nl": "Geen vegetarische opties beschikbaar" + } + }, + { + "if": "diet:vegetarian=limited", + "then": { + "nl": "Beperkte vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=yes", + "then": { + "nl": "Vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=only", + "then": { + "nl": "Enkel vegetarische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture", + "id": "Vegetarian (no friture)" }, { - "if": "diet:vegan=limited", - "then": { - "nl": "Beperkte veganistische opties zijn beschikbaar" - } + "question": { + "nl": "Heeft deze eetgelegenheid een veganistische optie?" + }, + "mappings": [ + { + "if": "diet:vegan=no", + "then": { + "nl": "Geen veganistische opties beschikbaar" + } + }, + { + "if": "diet:vegan=limited", + "then": { + "nl": "Beperkte veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=yes", + "then": { + "nl": "Veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=only", + "then": { + "nl": "Enkel veganistische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture", + "id": "Vegan (no friture)" }, { - "if": "diet:vegan=yes", - "then": { - "nl": "Veganistische opties zijn beschikbaar" - } + "question": { + "en": "Does this restaurant offer a halal menu?", + "nl": "Heeft dit restaurant halal opties?" + }, + "mappings": [ + { + "if": "diet:halal=no", + "then": { + "en": "There are no halal options available", + "nl": "Er zijn geen halal opties aanwezig" + } + }, + { + "if": "diet:halal=limited", + "then": { + "en": "There is a small halal menu", + "nl": "Er zijn een beperkt aantal halal opties" + } + }, + { + "if": "diet:halal=yes", + "then": { + "nl": "Halal menu verkrijgbaar", + "en": "There is a halal menu" + } + }, + { + "if": "diet:halal=only", + "then": { + "nl": "Enkel halal opties zijn beschikbaar", + "en": "Only halal options are available" + } + } + ], + "condition": "cuisine!=friture", + "id": "halal (no friture)" }, { - "if": "diet:vegan=only", - "then": { - "nl": "Enkel veganistische opties zijn beschikbaar" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "#": "halal (no friture)", - "question": { - "en": "Does this restaurant offer a halal menu?", - "nl": "Heeft dit restaurant halal opties?" - }, - "mappings": [ - { - "if": "diet:halal=no", - "then": { - "en": "There are no halal options available", - "nl": "Er zijn geen halal opties aanwezig" - } + "id": "friture-vegetarian", + "question": { + "nl": "Heeft deze frituur vegetarische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétariens ?" + }, + "mappings": [ + { + "if": "diet:vegetarian=yes", + "then": { + "nl": "Er zijn vegetarische snacks aanwezig", + "fr": "Des collations végétariens sont disponibles" + } + }, + { + "if": "diet:vegetarian=limited", + "then": { + "nl": "Slechts enkele vegetarische snacks", + "fr": "Quelques snacks végétariens seulement" + } + }, + { + "if": "diet:vegetarian=no", + "then": { + "nl": "Geen vegetarische snacks beschikbaar", + "fr": "Pas d'en-cas végétariens disponibles" + } + } + ], + "condition": "cuisine=friture" }, { - "if": "diet:halal=limited", - "then": { - "en": "There is a small halal menu", - "nl": "Er zijn een beperkt aantal halal opties" - } + "id": "friture-vegan", + "question": { + "nl": "Heeft deze frituur veganistische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" + }, + "mappings": [ + { + "if": "diet:vegan=yes", + "then": { + "nl": "Er zijn veganistische snacks aanwezig", + "fr": "Des collations végétaliens sont disponibles" + } + }, + { + "if": "diet:vegan=limited", + "then": { + "nl": "Slechts enkele veganistische snacks", + "fr": "Quelques snacks végétaliens seulement" + } + }, + { + "if": "diet:vegan=no", + "then": { + "nl": "Geen veganistische snacks beschikbaar", + "fr": "Pas d'en-cas végétaliens disponibles" + } + } + ], + "condition": "cuisine=friture" }, { - "if": "diet:halal=yes", - "then": { - "nl": "Halal menu verkrijgbaar", - "en": "There is a halal menu" - } + "id": "friture-oil", + "question": { + "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", + "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" + }, + "mappings": [ + { + "if": "friture:oil=vegetable", + "then": { + "nl": "Plantaardige olie", + "fr": "Huile végétale" + } + }, + { + "if": "friture:oil=animal", + "then": { + "nl": "Dierlijk vet", + "fr": "Graisse animale" + } + } + ], + "condition": "cuisine=friture" }, { - "if": "diet:halal=only", - "then": { - "nl": "Enkel halal opties zijn beschikbaar", - "en": "Only halal options are available" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "question": { - "nl": "Heeft deze frituur vegetarische snacks?", - "fr": "Cette friterie est-elle équipée de snacks végétariens ?" - }, - "mappings": [ - { - "if": "diet:vegetarian=yes", - "then": { - "nl": "Er zijn vegetarische snacks aanwezig", - "fr": "Des collations végétariens sont disponibles" - } + "id": "friture-take-your-container", + "question": { + "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", + "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
", + "en": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
", + "ja": "お客様が持参容器(調理用の鍋や小さな鍋など)をもってきた場合は、注文の梱包に使用されますか?
" + }, + "mappings": [ + { + "if": "reusable_packaging:accept=yes", + "then": { + "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", + "fr": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets", + "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", + "ja": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" + } + }, + { + "if": "reusable_packaging:accept=no", + "then": { + "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", + "fr": "Apporter ses propres contenants n’est pas permis", + "en": "Bringing your own container is not allowed", + "ja": "独自の容器を持参することはできません", + "ru": "Приносить свою тару не разрешено" + } + }, + { + "if": "reusable_packaging:accept=only", + "then": { + "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", + "en": "You must bring your own container to order here.", + "ja": "自身の容器が注文に必要。", + "fr": "Il est obligatoire d’apporter ses propres contenants" + } + } + ], + "condition": "cuisine=friture" }, + "dog-access" + ], + "filter": [ { - "if": "diet:vegetarian=limited", - "then": { - "nl": "Slechts enkele vegetarische snacks", - "fr": "Quelques snacks végétariens seulement" - } - }, - { - "if": "diet:vegetarian=no", - "then": { - "nl": "Geen vegetarische snacks beschikbaar", - "fr": "Pas d'en-cas végétariens disponibles" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Heeft deze frituur veganistische snacks?", - "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" - }, - "mappings": [ - { - "if": "diet:vegan=yes", - "then": { - "nl": "Er zijn veganistische snacks aanwezig", - "fr": "Des collations végétaliens sont disponibles" - } - }, - { - "if": "diet:vegan=limited", - "then": { - "nl": "Slechts enkele veganistische snacks", - "fr": "Quelques snacks végétaliens seulement" - } - }, - { - "if": "diet:vegan=no", - "then": { - "nl": "Geen veganistische snacks beschikbaar", - "fr": "Pas d'en-cas végétaliens disponibles" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", - "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" - }, - "mappings": [ - { - "if": "friture:oil=vegetable", - "then": { - "nl": "Plantaardige olie", - "fr": "Huile végétale" - } - }, - { - "if": "friture:oil=animal", - "then": { - "nl": "Dierlijk vet", - "fr": "Graisse animale" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", - "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
", - "en": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
", - "ja": "お客様が持参容器(調理用の鍋や小さな鍋など)をもってきた場合は、注文の梱包に使用されますか?
" - }, - "mappings": [ - { - "if": "reusable_packaging:accept=yes", - "then": { - "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", - "fr": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets", - "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", - "ja": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" - } - }, - { - "if": "reusable_packaging:accept=no", - "then": { - "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", - "fr": "Apporter ses propres contenants n’est pas permis", - "en": "Bringing your own container is not allowed", - "ja": "独自の容器を持参することはできません", - "ru": "Приносить свою тару не разрешено" - } - }, - { - "if": "reusable_packaging:accept=only", - "then": { - "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", - "en": "You must bring your own container to order here.", - "ja": "自身の容器が注文に必要。", - "fr": "Il est obligatoire d’apporter ses propres contenants" - } - } - ], - "condition": "cuisine=friture" - }, - "dog-access" - ], - "filter": [ - { - "options": [ - { - "question": { - "en": "Opened now", - "nl": "Nu geopened" - }, - "osmTags": "_isOpen=yes" - } - ] - }, - { - "options": [ - { - "question": { - "en": "Has a vegetarian menu", - "nl": "Heeft een vegetarisch menu" - }, - "osmTags": { - "or": [ - "diet:vegetarian=yes", - "diet:vegetarian=only", - "diet:vegan=yes", - "diet:vegan=only" + "id": "opened-now", + "options": [ + { + "question": { + "en": "Opened now", + "nl": "Nu geopened" + }, + "osmTags": "_isOpen=yes" + } ] - } - } - ] - }, - { - "options": [ + }, { - "question": { - "en": "Has a vegan menu", - "nl": "Heeft een veganistisch menu" - }, - "osmTags": { - "or": [ - "diet:vegan=yes", - "diet:vegan=only" + "id": "vegetarian", + "options": [ + { + "question": { + "en": "Has a vegetarian menu", + "nl": "Heeft een vegetarisch menu" + }, + "osmTags": { + "or": [ + "diet:vegetarian=yes", + "diet:vegetarian=only", + "diet:vegan=yes", + "diet:vegan=only" + ] + } + } ] - } - } - ] - }, - { - "options": [ + }, { - "question": { - "en": "Has a halal menu", - "nl": "Heeft een halal menu" - }, - "osmTags": { - "or": [ - "diet:halal=yes", - "diet:halal=only" + "id": "vegan", + "options": [ + { + "question": { + "en": "Has a vegan menu", + "nl": "Heeft een veganistisch menu" + }, + "osmTags": { + "or": [ + "diet:vegan=yes", + "diet:vegan=only" + ] + } + } + ] + }, + { + "id": "halal", + "options": [ + { + "question": { + "en": "Has a halal menu", + "nl": "Heeft een halal menu" + }, + "osmTags": { + "or": [ + "diet:halal=yes", + "diet:halal=only" + ] + } + } ] - } } - ] - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json index 68020ab52..25a6097ef 100644 --- a/assets/layers/ghost_bike/ghost_bike.json +++ b/assets/layers/ghost_bike/ghost_bike.json @@ -1,186 +1,191 @@ { - "id": "ghost_bike", - "name": { - "en": "Ghost bikes", - "nl": "Witte Fietsen", - "de": "Geisterrad", - "it": "Bici fantasma", - "fr": "Vélos fantômes", - "eo": "Fantombiciklo", - "es": "Bicicleta blanca", - "fi": "Haamupyörä", - "gl": "Bicicleta pantasma", - "hu": "Emlékkerékpár", - "ja": "ゴーストバイク", - "nb_NO": "Spøkelsessykler", - "pl": "Duch roweru", - "pt_BR": "Bicicleta fantasma", - "ru": "Велосипед Ghost", - "sv": "Spökcykel", - "zh_Hant": "幽靈單車" - }, - "source": { - "osmTags": "memorial=ghost_bike" - }, - "minzoom": 0, - "title": { - "render": { - "en": "Ghost bike", - "nl": "Witte Fiets", - "de": "Geisterrad", - "it": "Bici fantasma", - "fr": "Vélo fantôme", - "eo": "Fantombiciklo", - "es": "Bicicleta blanca", - "fi": "Haamupyörä", - "gl": "Bicicleta pantasma", - "hu": "Emlékkerékpár", - "ja": "ゴーストバイク", - "nb_NO": "Spøkelsessykler", - "pl": "Duch roweru", - "pt_BR": "Bicicleta fantasma", - "ru": "Велосипед Ghost", - "sv": "Spökcykel", - "zh_Hant": "幽靈單車" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Ghost bike in the remembrance of {name}", - "nl": "Witte fiets ter nagedachtenis van {name}", - "de": "Geisterrad im Gedenken an {name}", - "it": "Bici fantasma in ricordo di {name}", - "fr": "Vélo fantôme en souvenir de {name}" - } - } - ] - }, - "icon": "./assets/layers/ghost_bike/ghost_bike.svg", - "iconSize": "40,40,bottom", - "width": "5", - "color": "#000", - "wayHandling": 1, - "presets": [ - { - "title": { - "en": "Ghost bike", - "nl": "Witte fiets", + "id": "ghost_bike", + "name": { + "en": "Ghost bikes", + "nl": "Witte Fietsen", "de": "Geisterrad", "it": "Bici fantasma", - "fr": "Vélo fantôme" - }, - "tags": [ - "historic=memorial", - "memorial=ghost_bike" - ] - } - ], - "tagRenderings": [ - { - "render": { - "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", - "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", - "de": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird.", - "it": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente.", - "fr": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." - } + "fr": "Vélos fantômes", + "eo": "Fantombiciklo", + "es": "Bicicleta blanca", + "fi": "Haamupyörä", + "gl": "Bicicleta pantasma", + "hu": "Emlékkerékpár", + "ja": "ゴーストバイク", + "nb_NO": "Spøkelsessykler", + "pl": "Duch roweru", + "pt_BR": "Bicicleta fantasma", + "ru": "Велосипед Ghost", + "sv": "Spökcykel", + "zh_Hant": "幽靈單車" }, - "images", - { - "question": { - "en": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", - "nl": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", - "de": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", - "it": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", - "fr": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
" - }, - "render": { - "en": "In remembrance of {name}", - "nl": "Ter nagedachtenis van {name}", - "de": "Im Gedenken an {name}", - "it": "In ricordo di {name}", - "fr": "En souvenir de {name}", - "ru": "В знак памяти о {name}" - }, - "freeform": { - "key": "name" - }, - "mappings": [ + "source": { + "osmTags": "memorial=ghost_bike" + }, + "minzoom": 0, + "title": { + "render": { + "en": "Ghost bike", + "nl": "Witte Fiets", + "de": "Geisterrad", + "it": "Bici fantasma", + "fr": "Vélo fantôme", + "eo": "Fantombiciklo", + "es": "Bicicleta blanca", + "fi": "Haamupyörä", + "gl": "Bicicleta pantasma", + "hu": "Emlékkerékpár", + "ja": "ゴーストバイク", + "nb_NO": "Spøkelsessykler", + "pl": "Duch roweru", + "pt_BR": "Bicicleta fantasma", + "ru": "Велосипед Ghost", + "sv": "Spökcykel", + "zh_Hant": "幽靈單車" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Ghost bike in the remembrance of {name}", + "nl": "Witte fiets ter nagedachtenis van {name}", + "de": "Geisterrad im Gedenken an {name}", + "it": "Bici fantasma in ricordo di {name}", + "fr": "Vélo fantôme en souvenir de {name}" + } + } + ] + }, + "icon": "./assets/layers/ghost_bike/ghost_bike.svg", + "iconSize": "40,40,bottom", + "width": "5", + "color": "#000", + "wayHandling": 1, + "presets": [ { - "if": "noname=yes", - "then": { - "en": "No name is marked on the bike", - "nl": "De naam is niet aangeduid op de fiets", - "de": "Auf dem Fahrrad ist kein Name angegeben", - "it": "Nessun nome scritto sulla bici", - "fr": "Aucun nom n'est marqué sur le vélo" - } + "title": { + "en": "Ghost bike", + "nl": "Witte fiets", + "de": "Geisterrad", + "it": "Bici fantasma", + "fr": "Vélo fantôme" + }, + "tags": [ + "historic=memorial", + "memorial=ghost_bike" + ] } - ] - }, - { - "question": { - "en": "On what webpage can one find more information about the Ghost bike or the accident?", - "nl": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", - "de": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", - "it": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", - "fr": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?" - }, - "render": { - "en": "
More information is available", - "nl": "Meer informatie", - "de": "Mehr Informationen", - "it": "Sono disponibili ulteriori informazioni", - "ru": "Доступна более подробная информация", - "fr": "Plus d'informations sont disponibles", - "id": "Informasi lanjut tersedia" - }, - "freeform": { - "type": "url", - "key": "source" - } - }, - { - "question": { - "en": "What is the inscription on this Ghost bike?", - "nl": "Wat is het opschrift op deze witte fiets?", - "de": "Wie lautet die Inschrift auf diesem Geisterrad?", - "it": "Che cosa è scritto sulla bici fantasma?", - "fr": "Quelle est l'inscription sur ce vélo fantôme ?" - }, - "render": { - "en": "{inscription}", - "nl": "{inscription}", - "de": "{inscription}", - "ca": "{inscription}", - "fr": "{inscription}", - "it": "{inscription}", - "ru": "{inscription}", - "id": "{inscription}" - }, - "freeform": { - "key": "inscription" - } - }, - { - "question": { - "nl": "Wanneer werd deze witte fiets geplaatst?", - "en": "When was this Ghost bike installed?", - "it": "Quando è stata installata questa bici fantasma?", - "fr": "Quand ce vélo fantôme a-t-il été installée ?" - }, - "render": { - "nl": "Geplaatst op {start_date}", - "en": "Placed on {start_date}", - "it": "Piazzata in data {start_date}", - "fr": "Placé le {start_date}", - "ru": "Установлен {start_date}" - }, - "freeform": { - "key": "start_date", - "type": "date" - } - } - ] + ], + "tagRenderings": [ + { + "id": "ghost-bike-explanation", + "render": { + "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", + "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", + "de": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird.", + "it": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente.", + "fr": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." + } + }, + "images", + { + "question": { + "en": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", + "nl": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", + "de": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", + "it": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", + "fr": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
" + }, + "render": { + "en": "In remembrance of {name}", + "nl": "Ter nagedachtenis van {name}", + "de": "Im Gedenken an {name}", + "it": "In ricordo di {name}", + "fr": "En souvenir de {name}", + "ru": "В знак памяти о {name}" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": "noname=yes", + "then": { + "en": "No name is marked on the bike", + "nl": "De naam is niet aangeduid op de fiets", + "de": "Auf dem Fahrrad ist kein Name angegeben", + "it": "Nessun nome scritto sulla bici", + "fr": "Aucun nom n'est marqué sur le vélo" + } + } + ], + "id": "ghost_bike-name" + }, + { + "question": { + "en": "On what webpage can one find more information about the Ghost bike or the accident?", + "nl": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", + "de": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", + "it": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", + "fr": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?" + }, + "render": { + "en": "More information is available", + "nl": "Meer informatie", + "de": "Mehr Informationen", + "it": "Sono disponibili ulteriori informazioni", + "ru": "Доступна более подробная информация", + "fr": "Plus d'informations sont disponibles", + "id": "Informasi lanjut tersedia" + }, + "freeform": { + "type": "url", + "key": "source" + }, + "id": "ghost_bike-source" + }, + { + "question": { + "en": "What is the inscription on this Ghost bike?", + "nl": "Wat is het opschrift op deze witte fiets?", + "de": "Wie lautet die Inschrift auf diesem Geisterrad?", + "it": "Che cosa è scritto sulla bici fantasma?", + "fr": "Quelle est l'inscription sur ce vélo fantôme ?" + }, + "render": { + "en": "{inscription}", + "nl": "{inscription}", + "de": "{inscription}", + "ca": "{inscription}", + "fr": "{inscription}", + "it": "{inscription}", + "ru": "{inscription}", + "id": "{inscription}" + }, + "freeform": { + "key": "inscription" + }, + "id": "ghost_bike-inscription" + }, + { + "question": { + "nl": "Wanneer werd deze witte fiets geplaatst?", + "en": "When was this Ghost bike installed?", + "it": "Quando è stata installata questa bici fantasma?", + "fr": "Quand ce vélo fantôme a-t-il été installée ?" + }, + "render": { + "nl": "Geplaatst op {start_date}", + "en": "Placed on {start_date}", + "it": "Piazzata in data {start_date}", + "fr": "Placé le {start_date}", + "ru": "Установлен {start_date}" + }, + "freeform": { + "key": "start_date", + "type": "date" + }, + "id": "ghost_bike-start_date" + } + ] } \ No newline at end of file diff --git a/assets/layers/grass_in_parks/grass_in_parks.json b/assets/layers/grass_in_parks/grass_in_parks.json index 9a48eb2be..a95d6e0eb 100644 --- a/assets/layers/grass_in_parks/grass_in_parks.json +++ b/assets/layers/grass_in_parks/grass_in_parks.json @@ -1,53 +1,55 @@ { - "id": "grass_in_parks", - "name": { - "nl": "Toegankelijke grasvelden in parken" - }, - "source": { - "osmTags": { - "or": [ - "name=Park Oude God", - { - "and": [ - "landuse=grass", + "id": "grass_in_parks", + "name": { + "nl": "Toegankelijke grasvelden in parken" + }, + "source": { + "osmTags": { + "or": [ + "name=Park Oude God", + { + "and": [ + "landuse=grass", + { + "or": [ + "access=public", + "access=yes" + ] + } + ] + } + ] + }, + "overpassScript": "way[\"leisure\"=\"park\"];node(w);is_in;area._[\"leisure\"=\"park\"];(way(area)[\"landuse\"=\"grass\"]; node(w); );" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide in een park" + }, + "mappings": [ { - "or": [ - "access=public", - "access=yes" - ] + "if": "name~*", + "then": { + "nl": "{name}" + } } - ] - } - ] + ] }, - "overpassScript": "way[\"leisure\"=\"park\"];node(w);is_in;area._[\"leisure\"=\"park\"];(way(area)[\"landuse\"=\"grass\"]; node(w); );" - }, - "minzoom": 0, - "title": { - "render": { - "nl": "Speelweide in een park" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,center", + "width": "1", + "color": "#0f0", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "id": "explanation", + "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." + }, + { + "id": "grass-in-parks-reviews", + "render": "{reviews(name, landuse=grass )}" } - } ] - }, - "icon": "./assets/themes/playgrounds/playground.svg", - "iconSize": "40,40,center", - "width": "1", - "color": "#0f0", - "wayHandling": 2, - "tagRenderings": [ - "images", - { - "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." - }, - { - "render": "{reviews(name, landuse=grass )}" - } - ] } \ No newline at end of file diff --git a/assets/layers/information_board/information_board.json b/assets/layers/information_board/information_board.json index 4b0c47f4f..6f240fa4f 100644 --- a/assets/layers/information_board/information_board.json +++ b/assets/layers/information_board/information_board.json @@ -1,57 +1,57 @@ { - "id": "information_board", - "name": { - "nl": "Informatieborden", - "en": "Information boards", - "it": "Pannelli informativi", - "fr": "Panneaux d'informations", - "de": "Informationstafeln", - "ru": "Информационные щиты" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "information=board" - ] - } - }, - "title": { - "render": { - "nl": "Informatiebord", - "en": "Information board", - "it": "Pannello informativo", - "fr": "Panneau d'informations", - "de": "Informationstafel", - "ru": "Информационный щит" - } - }, - "tagRenderings": [ - "images" - ], - "icon": { - "render": "./assets/layers/information_board/board.svg" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "tourism=information", - "information=board" - ], - "title": { - "nl": "Informatiebord", - "en": "Information board", - "it": "Pannello informativo", - "fr": "Panneau d'informations", - "de": "Informationstafel", - "ru": "Информационный щит" - } - } - ] + "id": "information_board", + "name": { + "nl": "Informatieborden", + "en": "Information boards", + "it": "Pannelli informativi", + "fr": "Panneaux d'informations", + "de": "Informationstafeln", + "ru": "Информационные щиты" + }, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "information=board" + ] + } + }, + "title": { + "render": { + "nl": "Informatiebord", + "en": "Information board", + "it": "Pannello informativo", + "fr": "Panneau d'informations", + "de": "Informationstafel", + "ru": "Информационный щит" + } + }, + "tagRenderings": [ + "images" + ], + "icon": { + "render": "./assets/layers/information_board/board.svg" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "tourism=information", + "information=board" + ], + "title": { + "nl": "informatiebord", + "en": "information board", + "it": "pannello informativo", + "fr": "panneau d'informations", + "de": "informationstafel", + "ru": "Информационный щит" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/map/map.json b/assets/layers/map/map.json index 0f3374791..221bfa7ef 100644 --- a/assets/layers/map/map.json +++ b/assets/layers/map/map.json @@ -1,229 +1,231 @@ { - "id": "map", - "name": { - "en": "Maps", - "nl": "Kaarten", - "it": "Mappe", - "ru": "Карты", - "fr": "Cartes", - "de": "Karten" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "tourism=map", - "information=map" - ] - } - }, - "title": { - "render": { - "en": "Map", - "nl": "Kaart", - "it": "Mappa", - "ru": "Карта", - "fr": "Carte", - "de": "Karte" - } - }, - "description": { - "en": "A map, meant for tourists which is permanently installed in the public space", - "nl": "Een permantent geinstalleerde kaart", - "it": "Una mappa, destinata ai turisti e che è sistemata in maniera permanente in uno spazio pubblico", - "fr": "Une carte, destinée aux touristes, installée en permanence dans l'espace public" - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "On which data is this map based?", - "nl": "Op welke data is deze kaart gebaseerd?", - "it": "Su quali dati si basa questa mappa?", - "fr": "Sur quelles données cette carte est-elle basée ?", - "de": "Auf welchen Daten basiert diese Karte?" - }, - "mappings": [ - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "not:map_source=" - ] - }, - "then": { - "en": "This map is based on OpenStreetMap", - "nl": "Deze kaart is gebaseerd op OpenStreetMap", - "it": "Questa mappa si basa su OpenStreetMap", - "ru": "Эта карта основана на OpenStreetMap", - "fr": "Cette carte est basée sur OpenStreetMap", - "de": "Diese Karte basiert auf OpenStreetMap" - } - } - ], - "freeform": { - "key": "map_source" - }, - "render": { - "en": "This map is based on {map_source}", - "nl": "Deze kaart is gebaseerd op {map_source}", - "it": "Questa mappa si basa su {map_source}", - "ru": "Эта карта основана на {map_source}", - "fr": "Cette carte est basée sur {map_source}", - "de": "Diese Karte basiert auf {map_source}" - } + "id": "map", + "name": { + "en": "Maps", + "nl": "Kaarten", + "it": "Mappe", + "ru": "Карты", + "fr": "Cartes", + "de": "Karten" }, - { - "question": { - "en": "Is the OpenStreetMap-attribution given?", - "nl": "Is de attributie voor OpenStreetMap aanwezig?", - "it": "L’attribuzione a OpenStreetMap è presente?", - "de": "Ist die OpenStreetMap-Attribution vorhanden?", - "fr": "L’attribution à OpenStreetMap est elle-présente ?" - }, - "mappings": [ - { - "if": { - "and": [ - "map_source:attribution=yes" + "minzoom": 12, + "source": { + "osmTags": { + "or": [ + "tourism=map", + "information=map" ] - }, - "then": { - "en": "OpenStreetMap is clearly attributed, including the ODBL-license", - "nl": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" ", - "it": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL", - "de": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz", - "fr": "L’attribution est clairement inscrite ainsi que la licence ODBL" - } - }, - { - "if": { - "and": [ - "map_source:attribution=incomplete" - ] - }, - "then": { - "en": "OpenStreetMap is clearly attributed, but the license is not mentioned", - "nl": "OpenStreetMap is duidelijk aangegeven, maar de licentievermelding ontbreekt", - "it": "L’attribuzione a OpenStreetMap è chiaramente specificata ma la licenza non compare", - "de": "OpenStreetMap ist eindeutig attributiert, aber die Lizenz wird nicht erwähnt", - "fr": "L’attribution est clairement inscrite mais la licence est absente" - } - }, - { - "if": { - "and": [ - "map_source:attribution=sticker" - ] - }, - "then": { - "en": "OpenStreetMap wasn't mentioned, but someone put an OpenStreetMap-sticker on it", - "nl": "OpenStreetMap was oorspronkelijk niet aangeduid, maar iemand plaatste er een sticker", - "it": "Non era presente alcun cenno a OpenStreetMap ma qualcuno vi ha attaccato un adesivo di OpenStreetMap", - "de": "OpenStreetMap wurde nicht erwähnt, aber jemand hat einen OpenStreetMap-Aufkleber darauf geklebt", - "fr": "OpenStreetMap n’est pas mentionné, un sticker OpenStreetMap a été collé" - } - }, - { - "if": { - "and": [ - "map_source:attribution=none" - ] - }, - "then": { - "en": "There is no attribution at all", - "nl": "Er is geen attributie", - "it": "Non c’è alcuna attribuzione", - "fr": "Il n'y a aucune attribution", - "de": "Es gibt überhaupt keine Namensnennung" - } - }, - { - "if": { - "and": [ - "map_source:attribution=no" - ] - }, - "then": { - "nl": "Er is geen attributie", - "en": "There is no attribution at all", - "it": "Non c’è alcuna attribuzione", - "fr": "Il n'y a aucune attribution", - "de": "Es gibt überhaupt keine Namensnennung" - }, - "hideInAnswer": true } - ], - "condition": { - "or": [ - "map_source~(O|)pen(S|s)treet(M|m)ap", - "map_source=osm", - "map_source=OSM" + }, + "title": { + "render": { + "en": "Map", + "nl": "Kaart", + "it": "Mappa", + "ru": "Карта", + "fr": "Carte", + "de": "Karte" + } + }, + "description": { + "en": "A map, meant for tourists which is permanently installed in the public space", + "nl": "Een permantent geinstalleerde kaart", + "it": "Una mappa, destinata ai turisti e che è sistemata in maniera permanente in uno spazio pubblico", + "fr": "Une carte, destinée aux touristes, installée en permanence dans l'espace public" + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "On which data is this map based?", + "nl": "Op welke data is deze kaart gebaseerd?", + "it": "Su quali dati si basa questa mappa?", + "fr": "Sur quelles données cette carte est-elle basée ?", + "de": "Auf welchen Daten basiert diese Karte?" + }, + "mappings": [ + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "not:map_source=" + ] + }, + "then": { + "en": "This map is based on OpenStreetMap", + "nl": "Deze kaart is gebaseerd op OpenStreetMap", + "it": "Questa mappa si basa su OpenStreetMap", + "ru": "Эта карта основана на OpenStreetMap", + "fr": "Cette carte est basée sur OpenStreetMap", + "de": "Diese Karte basiert auf OpenStreetMap" + } + } + ], + "freeform": { + "key": "map_source" + }, + "render": { + "en": "This map is based on {map_source}", + "nl": "Deze kaart is gebaseerd op {map_source}", + "it": "Questa mappa si basa su {map_source}", + "ru": "Эта карта основана на {map_source}", + "fr": "Cette carte est basée sur {map_source}", + "de": "Diese Karte basiert auf {map_source}" + }, + "id": "map-map_source" + }, + { + "id": "map-attribution", + "question": { + "en": "Is the OpenStreetMap-attribution given?", + "nl": "Is de attributie voor OpenStreetMap aanwezig?", + "it": "L’attribuzione a OpenStreetMap è presente?", + "de": "Ist die OpenStreetMap-Attribution vorhanden?", + "fr": "L’attribution à OpenStreetMap est elle-présente ?" + }, + "mappings": [ + { + "if": { + "and": [ + "map_source:attribution=yes" + ] + }, + "then": { + "en": "OpenStreetMap is clearly attributed, including the ODBL-license", + "nl": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" ", + "it": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL", + "de": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz", + "fr": "L’attribution est clairement inscrite ainsi que la licence ODBL" + } + }, + { + "if": { + "and": [ + "map_source:attribution=incomplete" + ] + }, + "then": { + "en": "OpenStreetMap is clearly attributed, but the license is not mentioned", + "nl": "OpenStreetMap is duidelijk aangegeven, maar de licentievermelding ontbreekt", + "it": "L’attribuzione a OpenStreetMap è chiaramente specificata ma la licenza non compare", + "de": "OpenStreetMap ist eindeutig attributiert, aber die Lizenz wird nicht erwähnt", + "fr": "L’attribution est clairement inscrite mais la licence est absente" + } + }, + { + "if": { + "and": [ + "map_source:attribution=sticker" + ] + }, + "then": { + "en": "OpenStreetMap wasn't mentioned, but someone put an OpenStreetMap-sticker on it", + "nl": "OpenStreetMap was oorspronkelijk niet aangeduid, maar iemand plaatste er een sticker", + "it": "Non era presente alcun cenno a OpenStreetMap ma qualcuno vi ha attaccato un adesivo di OpenStreetMap", + "de": "OpenStreetMap wurde nicht erwähnt, aber jemand hat einen OpenStreetMap-Aufkleber darauf geklebt", + "fr": "OpenStreetMap n’est pas mentionné, un sticker OpenStreetMap a été collé" + } + }, + { + "if": { + "and": [ + "map_source:attribution=none" + ] + }, + "then": { + "en": "There is no attribution at all", + "nl": "Er is geen attributie", + "it": "Non c’è alcuna attribuzione", + "fr": "Il n'y a aucune attribution", + "de": "Es gibt überhaupt keine Namensnennung" + } + }, + { + "if": { + "and": [ + "map_source:attribution=no" + ] + }, + "then": { + "nl": "Er is geen attributie", + "en": "There is no attribution at all", + "it": "Non c’è alcuna attribuzione", + "fr": "Il n'y a aucune attribution", + "de": "Es gibt überhaupt keine Namensnennung" + }, + "hideInAnswer": true + } + ], + "condition": { + "or": [ + "map_source~(O|)pen(S|s)treet(M|m)ap", + "map_source=osm", + "map_source=OSM" + ] + } + } + ], + "icon": { + "render": "./assets/layers/map/map.svg", + "mappings": [ + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "map_source:attribution=sticker" + ] + }, + "then": "./assets/layers/map/map-stickered.svg" + }, + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "map_source:attribution=yes" + ] + }, + "then": "./assets/layers/map/osm-logo-white-bg.svg" + }, + { + "if": { + "and": [ + "map_source=OpenStreetMap" + ] + }, + "then": "./assets/layers/map/osm-logo-buggy-attr.svg" + } ] - } - } - ], - "icon": { - "render": "./assets/layers/map/map.svg", - "mappings": [ - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "map_source:attribution=sticker" - ] - }, - "then": "./assets/layers/map/map-stickered.svg" - }, - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "map_source:attribution=yes" - ] - }, - "then": "./assets/layers/map/osm-logo-white-bg.svg" - }, - { - "if": { - "and": [ - "map_source=OpenStreetMap" - ] - }, - "then": "./assets/layers/map/osm-logo-buggy-attr.svg" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "tourism=map" - ], - "title": { - "en": "Map", - "nl": "Kaart", - "it": "Mappa", - "ru": "Карта", - "fr": "Carte", - "de": "Karte" - }, - "description": { - "en": "Add a missing map", - "nl": "Voeg een ontbrekende kaart toe", - "it": "Aggiungi una mappa mancante", - "fr": "Ajouter une carte manquante", - "de": "Fehlende Karte hinzufügen" - } - } - ], - "wayHandling": 2 + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "tourism=map" + ], + "title": { + "en": "Map", + "nl": "Kaart", + "it": "Mappa", + "ru": "Карта", + "fr": "Carte", + "de": "Karte" + }, + "description": { + "en": "Add a missing map", + "nl": "Voeg een ontbrekende kaart toe", + "it": "Aggiungi una mappa mancante", + "fr": "Ajouter une carte manquante", + "de": "Fehlende Karte hinzufügen" + } + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index 3b4b7b7d4..c6fb976af 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -1,462 +1,464 @@ { - "id": "nature_reserve", - "name": { - "nl": "Natuurgebied" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "leisure=nature_reserve", + "id": "nature_reserve", + "name": { + "nl": "Natuurgebied" + }, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "leisure=nature_reserve", + { + "and": [ + "protect_class!=98", + "boundary=protected_area" + ] + } + ] + } + ] + } + }, + "title": { + "render": { + "nl": "Natuurgebied" + }, + "mappings": [ { - "and": [ - "protect_class!=98", - "boundary=protected_area" - ] + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } } - ] - } - ] - } - }, - "title": { - "render": { - "nl": "Natuurgebied" + ] }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] + "description": { + "nl": "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." + }, + "tagRenderings": [ + "images", + { + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } + ], + "id": "Access tag" }, - "then": { - "nl": "{name:nl}" - } - }, - { - "if": { - "and": [ - "name~*" - ] + { + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit gebied?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + }, + { + "if": { + "and": [ + "operator=Agentschap Natuur en Bos" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + } + } + ], + "id": "Operator tag" }, - "then": { - "nl": "{name}" + { + "render": { + "nl": "Dit gebied heet {name:nl}" + }, + "question": { + "nl": "Wat is de Nederlandstalige naam van dit gebied?" + }, + "freeform": { + "key": "name:nl" + }, + "condition": { + "and": [ + "name:nl~*" + ] + }, + "id": "Name:nl-tag" + }, + { + "render": { + "nl": "Dit gebied heet {name}" + }, + "question": { + "nl": "Wat is de naam van dit gebied?" + }, + "freeform": { + "key": "name", + "addExtraTags": [ + "noname=" + ] + }, + "condition": { + "and": [ + "name:nl=" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "noname=yes", + "name=" + ] + }, + "then": { + "nl": "Dit gebied heeft geen naam" + } + } + ], + "id": "Name tag" + }, + { + "question": { + "nl": "Zijn honden toegelaten in dit gebied?", + "en": "Are dogs allowed in this nature reserve?", + "it": "I cani sono ammessi in questa riserva naturale?", + "fr": "Les chiens sont-ils autorisés dans cette réserve naturelle ?", + "de": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" + }, + "condition": { + "or": [ + "access=yes", + "access=permissive", + "access=guided" + ] + }, + "mappings": [ + { + "if": "dog=leashed", + "then": { + "nl": "Honden moeten aan de leiband", + "en": "Dogs have to be leashed", + "it": "I cani devono essere tenuti al guinzaglio", + "fr": "Les chiens doivent être tenus en laisse", + "de": "Hunde müssen angeleint sein" + } + }, + { + "if": "dog=no", + "then": { + "nl": "Honden zijn niet toegestaan", + "en": "No dogs allowed", + "it": "I cani non sono ammessi", + "fr": "Chiens interdits", + "de": "Hunde sind nicht erlaubt" + } + }, + { + "if": "dog=yes", + "then": { + "nl": "Honden zijn welkom en mogen vrij rondlopen", + "en": "Dogs are allowed to roam freely", + "it": "I cani sono liberi di girare liberi", + "fr": "Les chiens sont autorisés à se promener librement", + "de": "Hunde dürfen frei herumlaufen" + } + } + ], + "id": "Dogs?" + }, + { + "question": { + "en": "On which webpage can one find more information about this nature reserve?", + "nl": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?", + "it": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?", + "fr": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?", + "de": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" + }, + "render": "{website}", + "freeform": { + "key": "website", + "type": "url" + }, + "id": "Website" + }, + { + "question": { + "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", + "en": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", + "it": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", + "fr": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public" + }, + "render": { + "nl": "{curator} is de beheerder van dit gebied", + "en": "{curator} is the curator of this nature reserve", + "it": "{curator} è il curatore di questa riserva naturale", + "fr": "{curator} est en charge de la conservation de la réserve" + }, + "freeform": { + "key": "curator", + "type": "string" + }, + "id": "Curator" + }, + { + "question": { + "nl": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", + "en": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", + "it": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", + "fr": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée" + }, + "render": { + "nl": "{email}", + "en": "{email}", + "ca": "{email}", + "de": "{email}", + "fr": "{email}", + "it": "{email}", + "ru": "{email}", + "id": "{email}" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "id": "Email" + }, + { + "question": { + "nl": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", + "en": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", + "it": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", + "fr": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié" + }, + "render": { + "nl": "{phone}", + "en": "{phone}", + "ca": "{phone}", + "de": "{phone}", + "fr": "{phone}", + "it": "{phone}", + "ru": "{phone}", + "id": "{phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "phone" + }, + { + "render": { + "nl": "Extra info: {description}" + }, + "freeform": { + "key": "description" + }, + "id": "Non-editable description {description}" + }, + { + "question": "Is er extra info die je kwijt wil?", + "render": { + "nl": "Extra info: {description:0}" + }, + "freeform": { + "key": "description:0" + }, + "id": "Editable description {description:0}" + }, + { + "render": { + "en": "Surface area: {_surface:ha}Ha", + "nl": "Totale oppervlakte: {_surface:ha}Ha", + "it": "Area: {_surface:ha} ha", + "fr": "Superficie : {_surface:ha} ha" + }, + "mappings": [ + { + "if": "_surface:ha=0", + "then": { + "*": "" + } + } + ], + "id": "Surface area" + } + ], + "wayHandling": 2, + "icon": { + "render": "./assets/themes/buurtnatuur/nature_reserve.svg" + }, + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#3c3" + }, + "presets": [ + { + "tags": [ + "leisure=nature_reserve", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "natuurreservaat" + }, + "description": { + "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" + } + } + ], + "filter": [ + { + "id": "access", + "options": [ + { + "question": { + "nl": "Vrij te bezoeken" + }, + "osmTags": "access=yes" + } + ] + }, + { + "id": "dogs", + "options": [ + { + "question": { + "nl": "Alle natuurgebieden" + } + }, + { + "question": { + "nl": "Honden mogen vrij rondlopen" + }, + "osmTags": "dog=yes" + }, + { + "question": { + "nl": "Honden welkom aan de leiband" + }, + "osmTags": { + "or": [ + "dog=yes", + "dog=leashed" + ] + } + } + ] } - } ] - }, - "description": { - "nl": "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." - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit gebied?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true - }, - { - "if": { - "and": [ - "operator=Agentschap Natuur en Bos" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" - } - } - ] - }, - { - "#": "Name:nl-tag", - "render": { - "nl": "Dit gebied heet {name:nl}" - }, - "question": { - "nl": "Wat is de Nederlandstalige naam van dit gebied?" - }, - "freeform": { - "key": "name:nl" - }, - "condition": { - "and": [ - "name:nl~*" - ] - } - }, - { - "#": "Name tag", - "render": { - "nl": "Dit gebied heet {name}" - }, - "question": { - "nl": "Wat is de naam van dit gebied?" - }, - "freeform": { - "key": "name", - "addExtraTags": [ - "noname=" - ] - }, - "condition": { - "and": [ - "name:nl=" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "noname=yes", - "name=" - ] - }, - "then": { - "nl": "Dit gebied heeft geen naam" - } - } - ] - }, - { - "#": "Dogs?", - "question": { - "nl": "Zijn honden toegelaten in dit gebied?", - "en": "Are dogs allowed in this nature reserve?", - "it": "I cani sono ammessi in questa riserva naturale?", - "fr": "Les chiens sont-ils autorisés dans cette réserve naturelle ?", - "de": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" - }, - "condition": { - "or": [ - "access=yes", - "access=permissive", - "access=guided" - ] - }, - "mappings": [ - { - "if": "dog=leashed", - "then": { - "nl": "Honden moeten aan de leiband", - "en": "Dogs have to be leashed", - "it": "I cani devono essere tenuti al guinzaglio", - "fr": "Les chiens doivent être tenus en laisse", - "de": "Hunde müssen angeleint sein" - } - }, - { - "if": "dog=no", - "then": { - "nl": "Honden zijn niet toegestaan", - "en": "No dogs allowed", - "it": "I cani non sono ammessi", - "fr": "Chiens interdits", - "de": "Hunde sind nicht erlaubt" - } - }, - { - "if": "dog=yes", - "then": { - "nl": "Honden zijn welkom en mogen vrij rondlopen", - "en": "Dogs are allowed to roam freely", - "it": "I cani sono liberi di girare liberi", - "fr": "Les chiens sont autorisés à se promener librement", - "de": "Hunde dürfen frei herumlaufen" - } - } - ] - }, - { - "#": "Website", - "question": { - "en": "On which webpage can one find more information about this nature reserve?", - "nl": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?", - "it": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?", - "fr": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?", - "de": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" - }, - "render": "{website}", - "freeform": { - "key": "website", - "type": "url" - } - }, - { - "#": "Curator", - "question": { - "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", - "en": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", - "it": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", - "fr": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public" - }, - "render": { - "nl": "{curator} is de beheerder van dit gebied", - "en": "{curator} is the curator of this nature reserve", - "it": "{curator} è il curatore di questa riserva naturale", - "fr": "{curator} est en charge de la conservation de la réserve" - }, - "freeform": { - "key": "curator", - "type": "string" - } - }, - { - "#": "Email", - "question": { - "nl": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", - "en": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", - "it": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", - "fr": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée" - }, - "render": { - "nl": "{email}", - "en": "{email}", - "ca": "{email}", - "de": "{email}", - "fr": "{email}", - "it": "{email}", - "ru": "{email}", - "id": "{email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "#": "phone", - "question": { - "nl": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", - "en": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", - "it": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", - "fr": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié" - }, - "render": { - "nl": "{phone}", - "en": "{phone}", - "ca": "{phone}", - "de": "{phone}", - "fr": "{phone}", - "it": "{phone}", - "ru": "{phone}", - "id": "{phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "#": "Non-editable description {description}", - "render": { - "nl": "Extra info: {description}" - }, - "freeform": { - "key": "description" - } - }, - { - "#": "Editable description {description:0}", - "question": "Is er extra info die je kwijt wil?", - "render": { - "nl": "Extra info: {description:0}" - }, - "freeform": { - "key": "description:0" - } - }, - { - "#": "Surface area", - "render": { - "en": "Surface area: {_surface:ha}Ha", - "nl": "Totale oppervlakte: {_surface:ha}Ha", - "it": "Area: {_surface:ha} ha", - "fr": "Superficie : {_surface:ha} ha" - }, - "mappings": [ - { - "if": "_surface:ha=0", - "then": { - "*": "" - } - } - ] - } - ], - "wayHandling": 2, - "icon": { - "render": "./assets/themes/buurtnatuur/nature_reserve.svg" - }, - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#3c3" - }, - "presets": [ - { - "tags": [ - "leisure=nature_reserve", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "title": { - "nl": "Natuurreservaat" - }, - "description": { - "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" - } - } - ], - "filter": [ - { - "options": [ - { - "question": { - "nl": "Vrij te bezoeken" - }, - "osmTags": "access=yes" - } - ] - }, - { - "options": [ - { - "question": { - "nl": "Alle natuurgebieden" - } - }, - { - "question": { - "nl": "Honden mogen vrij rondlopen" - }, - "osmTags": "dog=yes" - }, - { - "question": { - "nl": "Honden welkom aan de leiband" - }, - "osmTags": { - "or": [ - "dog=yes", - "dog=leashed" - ] - } - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/observation_tower/observation_tower.json b/assets/layers/observation_tower/observation_tower.json index 373621fe4..fa9a00262 100644 --- a/assets/layers/observation_tower/observation_tower.json +++ b/assets/layers/observation_tower/observation_tower.json @@ -1,183 +1,183 @@ { - "id": "observation_tower", - "name": { - "en": "Observation towers", - "nl": "Uitkijktorens" - }, - "minzoom": 8, - "title": { - "render": { - "en": "Observation tower", - "nl": "Uitkijktoren" + "id": "observation_tower", + "name": { + "en": "Observation towers", + "nl": "Uitkijktorens" }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "{name}", - "nl": "{name}" - } - } - ] - }, - "description": { - "en": "Towers with a panoramic view", - "nl": "Torens om van het uitzicht te genieten" - }, - "tagRenderings": [ - "images", - { - "#": "name", - "question": { - "en": "What is the name of this tower?", - "nl": "Heeft deze toren een naam?" - }, - "render": { - "en": "This tower is called {name}", - "nl": "Deze toren heet {name}" - }, - "freeform": { - "key": "name" - }, - "mappings": [ - { - "if": "noname=yes", - "then": { - "en": "This tower doesn't have a specific name", - "nl": "Deze toren heeft geen specifieke naam" - } - } - ] - }, - { - "#": "Height", - "question": { - "en": "What is the height of this tower?", - "nl": "Hoe hoog is deze toren?" - }, - "render": { - "en": "This tower is {height} high", - "nl": "Deze toren is {height} hoog" - }, - "freeform": { - "key": "height", - "type": "pfloat" - } - }, - { - "#": "Operator", - "question": { - "en": "Who maintains this tower?", - "nl": "Wie onderhoudt deze toren?" - }, - "render": { - "nl": "Wordt onderhouden door {operator}", - "en": "Maintained by {operator}" - }, - "freeform": { - "key": "operator" - } - }, - "website", - { - "#": "Fee", - "question": { - "en": "How much does one have to pay to enter this tower?", - "nl": "Hoeveel moet men betalen om deze toren te bezoeken?" - }, - "render": { - "en": "Visiting this tower costs {charge}", - "nl": "Deze toren bezoeken kost {charge}" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" + "minzoom": 8, + "title": { + "render": { + "en": "Observation tower", + "nl": "Uitkijktoren" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "{name}", + "nl": "{name}" + } + } ] - }, - "mappings": [ + }, + "description": { + "en": "Towers with a panoramic view", + "nl": "Torens om van het uitzicht te genieten" + }, + "tagRenderings": [ + "images", { - "if": { + "question": { + "en": "What is the name of this tower?", + "nl": "Heeft deze toren een naam?" + }, + "render": { + "en": "This tower is called {name}", + "nl": "Deze toren heet {name}" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": "noname=yes", + "then": { + "en": "This tower doesn't have a specific name", + "nl": "Deze toren heeft geen specifieke naam" + } + } + ], + "id": "name" + }, + { + "question": { + "en": "What is the height of this tower?", + "nl": "Hoe hoog is deze toren?" + }, + "render": { + "en": "This tower is {height} high", + "nl": "Deze toren is {height} hoog" + }, + "freeform": { + "key": "height", + "type": "pfloat" + }, + "id": "Height" + }, + { + "question": { + "en": "Who maintains this tower?", + "nl": "Wie onderhoudt deze toren?" + }, + "render": { + "nl": "Wordt onderhouden door {operator}", + "en": "Maintained by {operator}" + }, + "freeform": { + "key": "operator" + }, + "id": "Operator" + }, + "website", + { + "question": { + "en": "How much does one have to pay to enter this tower?", + "nl": "Hoeveel moet men betalen om deze toren te bezoeken?" + }, + "render": { + "en": "Visiting this tower costs {charge}", + "nl": "Deze toren bezoeken kost {charge}" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Free to visit", + "nl": "Gratis te bezoeken" + } + } + ], + "id": "Fee" + }, + { + "builtin": "payment-options", + "override": { + "condition": { + "or": [ + "fee=yes", + "charge~*" + ] + } + }, + "id": "Payment methods" + }, + "wheelchair-access" + ], + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/observation_tower/Tower_observation.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "man_made=tower", + "tower:type=observation" + ], + "title": { + "en": "observation tower", + "nl": "Uitkijktoren" + }, + "description": { + "nl": "Een publiek toegankelijke uitkijktoren" + } + } + ], + "source": { + "osmTags": { "and": [ - "fee=no", - "charge=" + "tower:type=observation" ] - }, - "then": { - "en": "Free to visit", - "nl": "Gratis te bezoeken" - } } - ] }, - { - "#": "Payment methods", - "builtin": "payment-options", - "override": { - "condition": { - "or": [ - "fee=yes", - "charge~*" - ] - } - } - }, - "wheelchair-access" - ], - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/observation_tower/Tower_observation.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "man_made=tower", - "tower:type=observation" - ], - "title": { - "en": "observation tower", - "nl": "Uitkijktoren" - }, - "description": { - "nl": "Een publiek toegankelijke uitkijktoren" - } - } - ], - "source": { - "osmTags": { - "and": [ - "tower:type=observation" - ] - } - }, - "units": [ - { - "appliesToKey": [ - "height" - ], - "applicableUnits": [ + "units": [ { - "canonicalDenomination": "m", - "alternativeDenomination": [ - "meter", - "mtr" - ], - "human": { - "nl": " meter", - "en": " meter" - } + "appliesToKey": [ + "height" + ], + "applicableUnits": [ + { + "canonicalDenomination": "m", + "alternativeDenomination": [ + "meter", + "mtr" + ], + "human": { + "nl": " meter", + "en": " meter" + } + } + ], + "eraseInvalidValues": true } - ], - "eraseInvalidValues": true - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index d4d1cab73..42f09f53e 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -1,192 +1,85 @@ { - "id": "parking", - "name": { - "nl": "parking" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "amenity=parking", - "amenity=motorcycle_parking", - "amenity=bicycle_parking" - ] - } - ] - } - }, - "title": { - "render": { - "nl": "Parking" + "id": "parking", + "name": { + "nl": "Parking" }, - "mappings": [ - { - "if": "amenity=parking", - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "amenity=parking", + "amenity=motorcycle_parking", + "amenity=bicycle_parking" + ] + } + ] } - }, - { - "if": "amenity=motorcycle_parking", - "then": { - "nl": "{name}" + }, + "title": { + "render": { + "nl": "Parking" + }, + "mappings": [ + { + "if": "amenity=parking", + "then": { + "nl": "{name:nl}" + } + }, + { + "if": "amenity=motorcycle_parking", + "then": { + "nl": "{name}" + } + }, + { + "if": "amenity=bicycle_parking", + "then": { + "nl": "Fietsenstalling" + } + } + ] + }, + "icon": { + "render": "./assets/layers/parking/parking.svg" + }, + "description": { + "nl": "Parking" + }, + "tagRenderings": [ + "images" + ], + "wayHandling": 1, + "iconSize": { + "render": "36,36,center" + }, + "color": { + "render": "#E1AD01" + }, + "presets": [ + { + "tags": [ + "amenity=bicycle_parking" + ], + "title": { + "nl": "fietsparking" + }, + "description": { + "nl": "Voeg hier een fietsenstalling toe" + } + }, + { + "tags": [ + "amenity=parking" + ], + "title": { + "nl": "parking" + }, + "description": { + "nl": "Voeg hier een parking voor auto's toe" + } } - }, - { - "if": "amenity=bicycle_parking", - "then": { - "nl": "Fietsenstalling" - } - } ] - }, - "icon": { - "render": "./assets/layers/parking/parking.svg" - }, - "description": { - "nl": "Parking" - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit pad?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true - } - ] - } - ], - "wayHandling": 1, - "iconSize": { - "render": "36,36,center" - }, - "color": { - "render": "#E1AD01" - }, - "presets": [ - { - "tags": [ - "amenity=parking", - "amenity=motorcycle_parking", - "amenity=bicycle_parking", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "title": { - "nl": "Paden" - }, - "description": { - "nl": "Voeg een ontbrekend, erkend pad toe." - } - } - ] } \ No newline at end of file diff --git a/assets/layers/picnic_table/picnic_table.json b/assets/layers/picnic_table/picnic_table.json index e35c08ca0..c414410fe 100644 --- a/assets/layers/picnic_table/picnic_table.json +++ b/assets/layers/picnic_table/picnic_table.json @@ -1,104 +1,105 @@ { - "id": "picnic_table", - "name": { - "en": "Picnic tables", - "nl": "Picnictafels", - "it": "Tavoli da picnic", - "ru": "Столы для пикника", - "fr": "Tables de pique-nique", - "de": "Picknick-Tische" - }, - "minzoom": 12, - "source": { - "osmTags": "leisure=picnic_table" - }, - "title": { - "render": { - "en": "Picnic table", - "nl": "Picnictafel", - "it": "Tavolo da picnic", - "ru": "Стол для пикника", - "fr": "Table de pique-nique", - "de": "Picknick-Tisch" - } - }, - "description": { - "en": "The layer showing picnic tables", - "nl": "Deze laag toont picnictafels", - "it": "Il livello che mostra i tavoli da picnic", - "fr": "La couche montrant les tables de pique-nique", - "ru": "Слой, отображающий столы для пикника" - }, - "tagRenderings": [ - { - "question": { - "en": "What material is this picnic table made of?", - "nl": "Van welk materiaal is deze picnictafel gemaakt?", - "it": "Di che materiale è fatto questo tavolo da picnic?", - "de": "Aus welchem Material besteht dieser Picknicktisch?", - "ru": "Из чего изготовлен этот стол для пикника?", - "fr": "En quel matériau est faite la table de pique-nique ?" - }, - "render": { - "en": "This picnic table is made of {material}", - "nl": "Deze picnictafel is gemaakt van {material}", - "it": "Questo tavolo da picnic è fatto di {material}", - "de": "Dieser Picknicktisch besteht aus {material}", - "ru": "Этот стол для пикника сделан из {material}", - "fr": "La table est faite en {material}" - }, - "freeform": { - "key": "material" - }, - "mappings": [ - { - "if": "material=wood", - "then": { - "en": "This is a wooden picnic table", - "nl": "Deze picnictafel is gemaakt uit hout", - "it": "È un tavolo da picnic in legno", - "ru": "Это деревянный стол для пикника", - "de": "Dies ist ein Picknicktisch aus Holz", - "fr": "C’est une table en bois" - } - }, - { - "if": "material=concrete", - "then": { - "en": "This is a concrete picnic table", - "nl": "Deze picnictafel is gemaakt uit beton", - "it": "È un tavolo da picnic in cemento", - "ru": "Это бетонный стол для пикника", - "de": "Dies ist ein Picknicktisch aus Beton", - "fr": "C’est une table en béton" - } + "id": "picnic_table", + "name": { + "en": "Picnic tables", + "nl": "Picnictafels", + "it": "Tavoli da picnic", + "ru": "Столы для пикника", + "fr": "Tables de pique-nique", + "de": "Picknick-Tische" + }, + "minzoom": 12, + "source": { + "osmTags": "leisure=picnic_table" + }, + "title": { + "render": { + "en": "Picnic table", + "nl": "Picnictafel", + "it": "Tavolo da picnic", + "ru": "Стол для пикника", + "fr": "Table de pique-nique", + "de": "Picknick-Tisch" } - ] - } - ], - "icon": { - "render": "circle:#e6cf39;./assets/layers/picnic_table/picnic_table.svg" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "leisure=picnic_table" - ], - "title": { - "en": "Picnic table", - "nl": "Picnic-tafel", - "it": "Tavolo da picnic", - "ru": "Стол для пикника", - "de": "Picknicktisch", - "fr": "Table de pique-nique" - } - } - ], - "wayHandling": 1 + }, + "description": { + "en": "The layer showing picnic tables", + "nl": "Deze laag toont picnictafels", + "it": "Il livello che mostra i tavoli da picnic", + "fr": "La couche montrant les tables de pique-nique", + "ru": "Слой, отображающий столы для пикника" + }, + "tagRenderings": [ + { + "question": { + "en": "What material is this picnic table made of?", + "nl": "Van welk materiaal is deze picnictafel gemaakt?", + "it": "Di che materiale è fatto questo tavolo da picnic?", + "de": "Aus welchem Material besteht dieser Picknicktisch?", + "ru": "Из чего изготовлен этот стол для пикника?", + "fr": "En quel matériau est faite la table de pique-nique ?" + }, + "render": { + "en": "This picnic table is made of {material}", + "nl": "Deze picnictafel is gemaakt van {material}", + "it": "Questo tavolo da picnic è fatto di {material}", + "de": "Dieser Picknicktisch besteht aus {material}", + "ru": "Этот стол для пикника сделан из {material}", + "fr": "La table est faite en {material}" + }, + "freeform": { + "key": "material" + }, + "mappings": [ + { + "if": "material=wood", + "then": { + "en": "This is a wooden picnic table", + "nl": "Deze picnictafel is gemaakt uit hout", + "it": "È un tavolo da picnic in legno", + "ru": "Это деревянный стол для пикника", + "de": "Dies ist ein Picknicktisch aus Holz", + "fr": "C’est une table en bois" + } + }, + { + "if": "material=concrete", + "then": { + "en": "This is a concrete picnic table", + "nl": "Deze picnictafel is gemaakt uit beton", + "it": "È un tavolo da picnic in cemento", + "ru": "Это бетонный стол для пикника", + "de": "Dies ist ein Picknicktisch aus Beton", + "fr": "C’est une table en béton" + } + } + ], + "id": "picnic_table-material" + } + ], + "icon": { + "render": "circle:#e6cf39;./assets/layers/picnic_table/picnic_table.svg" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "leisure=picnic_table" + ], + "title": { + "en": "picnic table", + "nl": "picnic-tafel", + "it": "tavolo da picnic", + "ru": "Стол для пикника", + "de": "picknicktisch", + "fr": "table de pique-nique" + } + } + ], + "wayHandling": 1 } \ No newline at end of file diff --git a/assets/layers/play_forest/play_forest.json b/assets/layers/play_forest/play_forest.json index 5bbc4b512..0b1f2485e 100644 --- a/assets/layers/play_forest/play_forest.json +++ b/assets/layers/play_forest/play_forest.json @@ -1,115 +1,120 @@ { - "id": "play_forest", - "name": { - "nl": "Speelbossen" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "playground=forest" - ] - } - }, - "title": { - "render": { - "nl": "Speelbos" + "id": "play_forest", + "name": { + "nl": "Speelbossen" }, - "mappings": [ - { - "if": "name~Speelbos.*", - "then": { - "nl": "{name}" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "playground=forest" + ] } - }, - { - "if": "name~*", - "then": { - "nl": "Speelbos {name}" - } - } - ] - }, - "description": { - "nl": "Een speelbos is een vrij toegankelijke zone in een bos" - }, - "tagRenderings": [ - "images", - { - "question": "Wie beheert dit gebied?", - "render": "Dit gebied wordt beheerd door {operator}", - "freeform": { - "key": "operator" - }, - "mappings": [ + }, + "title": { + "render": { + "nl": "Speelbos" + }, + "mappings": [ + { + "if": "name~Speelbos.*", + "then": { + "nl": "{name}" + } + }, + { + "if": "name~*", + "then": { + "nl": "Speelbos {name}" + } + } + ] + }, + "description": { + "nl": "Een speelbos is een vrij toegankelijke zone in een bos" + }, + "tagRenderings": [ + "images", { - "if": "operator~[aA][nN][bB]", - "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos", - "hideInAnswer": true + "question": "Wie beheert dit gebied?", + "render": "Dit gebied wordt beheerd door {operator}", + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": "operator~[aA][nN][bB]", + "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos", + "hideInAnswer": true + }, + { + "if": "operator=Agenstchap Natuur en Bos", + "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + } + ], + "id": "play_forest-operator" }, { - "if": "operator=Agenstchap Natuur en Bos", - "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" - } - ] - }, - { - "question": "Wanneer is deze speelzone toegankelijk?", - "mappings": [ - { - "if": "opening_hours=08:00-22:00", - "then": "Het hele jaar door overdag toegankelijk (van 08:00 tot 22:00)" + "id": "play_forest-opening_hours", + "question": "Wanneer is deze speelzone toegankelijk?", + "mappings": [ + { + "if": "opening_hours=08:00-22:00", + "then": "Het hele jaar door overdag toegankelijk (van 08:00 tot 22:00)" + }, + { + "if": "opening_hours=Jul-Aug 08:00-22:00", + "then": "Enkel in de zomervakantie en overdag toegankelijk (van 1 juli tot 31 augustus, van 08:00 tot 22:00" + } + ] }, { - "if": "opening_hours=Jul-Aug 08:00-22:00", - "then": "Enkel in de zomervakantie en overdag toegankelijk (van 1 juli tot 31 augustus, van 08:00 tot 22:00" + "question": "Wie kan men emailen indien er problemen zijn met de speelzone?", + "render": "De bevoegde dienst kan bereikt worden via {email}", + "freeform": { + "key": "email", + "type": "email" + }, + "id": "play_forest-email" + }, + { + "question": "Wie kan men bellen indien er problemen zijn met de speelzone?", + "render": "De bevoegde dienst kan getelefoneerd worden via {phone}", + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "play_forest-phone" + }, + "questions", + { + "id": "play_forest-reviews", + "render": "{reviews(name, play_forest)}" } - ] + ], + "hideFromOverview": false, + "icon": { + "render": "./assets/layers/play_forest/icon.svg" }, - { - "question": "Wie kan men emailen indien er problemen zijn met de speelzone?", - "render": "De bevoegde dienst kan bereikt worden via {email}", - "freeform": { - "key": "email", - "type": "email" - } + "width": { + "render": "2" }, - { - "question": "Wie kan men bellen indien er problemen zijn met de speelzone?", - "render": "De bevoegde dienst kan getelefoneerd worden via {phone}", - "freeform": { - "key": "phone", - "type": "phone" - } + "iconSize": { + "render": "40,40,center" }, - "questions", - { - "render": "{reviews(name, play_forest)}" - } - ], - "hideFromOverview": false, - "icon": { - "render": "./assets/layers/play_forest/icon.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#007055" - }, - "presets": [ - { - "title": "Speelbos", - "tags": [ - "leisure=playground", - "playground=forest", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "description": "Een zone in het bos, duidelijk gemarkeerd als speelzone met de overeenkomstige borden.
" - } - ], - "wayHandling": 2 + "color": { + "render": "#007055" + }, + "presets": [ + { + "title": "Speelbos", + "tags": [ + "leisure=playground", + "playground=forest", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "description": "Een zone in het bos, duidelijk gemarkeerd als speelzone met de overeenkomstige borden.
" + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 6b6fe357f..9e7daea5e 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -1,520 +1,531 @@ { - "id": "playground", - "name": { - "nl": "Speeltuinen", - "en": "Playgrounds", - "ru": "Детские площадки", - "de": "Spielplätze", - "it": "Campi da gioco", - "fr": "Aire de jeu" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "leisure=playground", - "playground!=forest" - ] - } - }, - "calculatedTags": [ - "_size_classification=Number(feat.properties._surface) < 10 ? 'small' : (Number(feat.properties._surface) < 100 ? 'medium' : 'large') " - ], - "description": { - "nl": "Speeltuinen", - "en": "Playgrounds", - "it": "Parchi giochi", - "ru": "Детские площадки", - "de": "Spielplätze", - "fr": "Aire de jeu" - }, - "title": { - "render": { - "nl": "Speeltuin", - "en": "Playground", - "it": "Parco giochi", - "ru": "Детская площадка", - "de": "Spielplatz", - "fr": "Aire de jeu" + "id": "playground", + "name": { + "nl": "Speeltuinen", + "en": "Playgrounds", + "ru": "Детские площадки", + "de": "Spielplätze", + "it": "Campi da gioco", + "fr": "Aire de jeu" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "Speeltuin {name}", - "en": "Playground {name}", - "it": "Parco giochi {name}", - "ru": "Детская площадка {name}", - "de": "Spielplatz {name}", - "fr": "Aire de jeu {name}" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "leisure=playground", + "playground!=forest" + ] } - } - ] - }, - "tagRenderings": [ - "images", - { - "question": { - "nl": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", - "en": "Which is the surface of this playground?
If there are multiple, select the most occuring one", - "it": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", - "de": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", - "fr": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale" - }, - "render": { - "nl": "De ondergrond is {surface}", - "en": "The surface is {surface}", - "it": "La superficie è {surface}", - "ru": "Поверхность - {surface}", - "de": "Die Oberfläche ist {surface}", - "fr": "La surface est en {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "en": "The surface is grass", - "it": "La superficie è prato", - "ru": "Поверхность - трава", - "de": "Die Oberfläche ist Gras", - "fr": "La surface est en gazon" - } - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "en": "The surface is sand", - "it": "La superficie è sabbia", - "ru": "Поверхность - песок", - "de": "Die Oberfläche ist Sand", - "fr": "La surface est en sable" - } - }, - { - "if": "surface=woodchips", - "then": { - "nl": "De ondergrond bestaat uit houtsnippers", - "en": "The surface consist of woodchips", - "it": "La superficie consiste di trucioli di legno", - "de": "Die Oberfläche besteht aus Holzschnitzeln", - "ru": "Покрытие из щепы", - "fr": "La surface est en copeaux de bois" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "en": "The surface is paving stones", - "it": "La superficie è mattonelle regolari", - "ru": "Поверхность - брусчатка", - "de": "Die Oberfläche ist Pflastersteine", - "fr": "La surface est en pavés" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "en": "The surface is asphalt", - "it": "La superficie è asfalto", - "ru": "Поверхность - асфальт", - "de": "Die Oberfläche ist Asphalt", - "fr": "La surface est en bitume" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "en": "The surface is concrete", - "it": "La superficie è cemento", - "ru": "Поверхность - бетон", - "de": "Die Oberfläche ist Beton", - "fr": "La surface est en béton" - } - }, - { - "if": "surface=unpaved", - "then": { - "nl": "De ondergrond is onverhard", - "en": "The surface is unpaved", - "it": "La superficie è non pavimentato", - "de": "Die Oberfläche ist unbefestigt", - "fr": "La surface n’a pas de revêtement" - }, - "hideInAnswer": true - }, - { - "if": "surface=paved", - "then": { - "nl": "De ondergrond is verhard", - "en": "The surface is paved", - "it": "La superficie è pavimentato", - "de": "Die Oberfläche ist befestigt", - "fr": "La surface a un revêtement" - }, - "hideInAnswer": true - } - ] }, - { - "question": { - "nl": "Is deze speeltuin 's nachts verlicht?", - "en": "Is this playground lit at night?", - "it": "È illuminato di notte questo parco giochi?", - "fr": "Ce terrain de jeux est-il éclairé la nuit ?", - "de": "Ist dieser Spielplatz nachts beleuchtet?", - "ru": "Эта игровая площадка освещается ночью?" - }, - "mappings": [ - { - "if": "lit=yes", - "then": { - "nl": "Deze speeltuin is 's nachts verlicht", - "en": "This playground is lit at night", - "it": "Questo parco giochi è illuminato di notte", - "de": "Dieser Spielplatz ist nachts beleuchtet", - "ru": "Эта детская площадка освещается ночью", - "fr": "L’aire de jeu est éclairée de nuit" - } - }, - { - "if": "lit=no", - "then": { - "nl": "Deze speeltuin is 's nachts niet verlicht", - "en": "This playground is not lit at night", - "it": "Questo parco giochi non è illuminato di notte", - "de": "Dieser Spielplatz ist nachts nicht beleuchtet", - "ru": "Эта детская площадка не освещается ночью", - "fr": "L’aire de jeu n’est pas éclairée de nuit" - } - } - ] + "calculatedTags": [ + "_size_classification=Number(feat.properties._surface) < 10 ? 'small' : (Number(feat.properties._surface) < 100 ? 'medium' : 'large') " + ], + "description": { + "nl": "Speeltuinen", + "en": "Playgrounds", + "it": "Parchi giochi", + "ru": "Детские площадки", + "de": "Spielplätze", + "fr": "Aire de jeu" }, - { - "render": { - "nl": "Toegankelijk vanaf {min_age} jaar oud", - "en": "Accessible to kids older than {min_age} years", - "it": "Accessibile ai bambini di almeno {min_age} anni", - "ru": "Доступно для детей старше {min_age} лет", - "fr": "Accessible aux enfants de plus de {min_age} ans" - }, - "question": { - "nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", - "en": "What is the minimum age required to access this playground?", - "it": "Qual è l’età minima per accedere a questo parco giochi?", - "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", - "ru": "С какого возраста доступна эта детская площадка?" - }, - "freeform": { - "key": "min_age", - "type": "pnat" - } - }, - { - "render": { - "nl": "Toegankelijk tot {max_age}", - "en": "Accessible to kids of at most {max_age}", - "it": "Accessibile ai bambini di età inferiore a {max_age}", - "fr": "Accessible aux enfants de {max_age} au maximum", - "ru": "Доступно детям до {max_age}" - }, - "question": { - "nl": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", - "en": "What is the maximum age allowed to access this playground?", - "it": "Qual è l’età massima per accedere a questo parco giochi?", - "fr": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?" - }, - "freeform": { - "key": "max_age", - "type": "pnat" - } - }, - { - "question": { - "nl": "Wie beheert deze speeltuin?", - "en": "Who operates this playground?", - "it": "Chi è il responsabile di questo parco giochi?", - "de": "Wer betreibt diesen Spielplatz?", - "fr": "Qui est en charge de l’exploitation de l’aire de jeu ?" - }, - "render": { - "nl": "Beheer door {operator}", - "en": "Operated by {operator}", - "it": "Gestito da {operator}", - "fr": "Exploité par {operator}", - "de": "Betrieben von {operator}" - }, - "freeform": { - "key": "operator" - } - }, - { - "question": { - "nl": "Is deze speeltuin vrij toegankelijk voor het publiek?", - "en": "Is this playground accessible to the general public?", - "it": "Questo parco giochi è pubblicamente accessibile?", - "de": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?", - "fr": "L’aire de jeu est-elle accessible au public ?" - }, - "mappings": [ - { - "if": "access=", - "then": { - "en": "Accessible to the general public", - "nl": "Vrij toegankelijk voor het publiek", - "it": "Accessibile pubblicamente", - "de": "Zugänglich für die Allgemeinheit", - "fr": "Accessible au public" - }, - "hideInAnswer": true + "title": { + "render": { + "nl": "Speeltuin", + "en": "Playground", + "it": "Parco giochi", + "ru": "Детская площадка", + "de": "Spielplatz", + "fr": "Aire de jeu" }, - { - "if": "access=yes", - "then": { - "en": "Accessible to the general public", - "nl": "Vrij toegankelijk voor het publiek", - "it": "Accessibile pubblicamente", - "de": "Zugänglich für die Allgemeinheit", - "fr": "Accessible au public" - } - }, - { - "if": "access=customers", - "then": { - "en": "Only accessible for clients of the operating business", - "nl": "Enkel toegankelijk voor klanten van de bijhorende zaak", - "it": "Accessibile solamente ai clienti dell’attività che lo gestisce", - "de": "Nur für Kunden des Betreibers zugänglich", - "fr": "Réservée aux clients" - } - }, - { - "if": "access=students", - "then": { - "en": "Only accessible to students of the school", - "nl": "Vrij toegankelijk voor scholieren van de school", - "it": "Accessibile solamente agli studenti della scuola", - "de": "Nur für Schüler der Schule zugänglich", - "fr": "Réservée aux élèves de l’école" - } - }, - { - "if": "access=private", - "then": { - "en": "Not accessible", - "nl": "Niet vrij toegankelijk", - "it": "Non accessibile", - "ru": "Недоступно", - "fr": "Non accessible", - "de": "Nicht zugänglich" - } - } - ] - }, - { - "question": { - "nl": "Wie kan men emailen indien er problemen zijn met de speeltuin?", - "en": "What is the email address of the playground maintainer?", - "it": "Qual è l’indirizzo email del gestore di questo parco giochi?", - "fr": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", - "de": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?" - }, - "render": { - "nl": "De bevoegde dienst kan bereikt worden via {email}", - "en": "{email}", - "ca": "{email}", - "de": "{email}", - "fr": "{email}", - "it": "{email}", - "ru": "{email}", - "id": "{email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "question": { - "nl": "Wie kan men bellen indien er problemen zijn met de speeltuin?", - "en": "What is the phone number of the playground maintainer?", - "fr": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", - "it": "Qual è il numero di telefono del gestore del campetto?" - }, - "render": { - "nl": "De bevoegde dienst kan getelefoneerd worden via {phone}", - "en": "{phone}", - "ca": "{phone}", - "de": "{phone}", - "fr": "{phone}", - "ru": "{phone}", - "id": "{phone}", - "it": "{phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "nl": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?", - "en": "Is this playground accessible to wheelchair users?", - "fr": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?", - "de": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?", - "it": "Il campetto è accessibile a persone in sedia a rotelle?", - "ru": "Доступна ли детская площадка пользователям кресел-колясок?" - }, - "mappings": [ - { - "if": "wheelchair=yes", - "then": { - "nl": "Geheel toegankelijk voor rolstoelgebruikers", - "en": "Completely accessible for wheelchair users", - "fr": "Entièrement accessible aux personnes en fauteuil roulant", - "de": "Vollständig zugänglich für Rollstuhlfahrer", - "it": "Completamente accessibile in sedia a rotelle", - "ru": "Полностью доступна пользователям кресел-колясок" - } - }, - { - "if": "wheelchair=limited", - "then": { - "nl": "Beperkt toegankelijk voor rolstoelgebruikers", - "en": "Limited accessibility for wheelchair users", - "fr": "Accessibilité limitée pour les personnes en fauteuil roulant", - "de": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer", - "it": "Accesso limitato in sedia a rotelle", - "ru": "Частично доступна пользователям кресел-колясок" - } - }, - { - "if": "wheelchair=no", - "then": { - "nl": "Niet toegankelijk voor rolstoelgebruikers", - "en": "Not accessible for wheelchair users", - "fr": "Non accessible aux personnes en fauteuil roulant", - "de": "Nicht zugänglich für Rollstuhlfahrer", - "it": "Non accessibile in sedia a rotelle", - "ru": "Недоступна пользователям кресел-колясок" - } - } - ] - }, - { - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "render": "{opening_hours_table(opening_hours)}", - "question": { - "nl": "Op welke uren is deze speeltuin toegankelijk?", - "en": "When is this playground accessible?", - "fr": "Quand ce terrain de jeux est-il accessible ?", - "it": "Quando si può accedere a questo campetto?", - "ru": "Когда открыта эта игровая площадка?" - }, - "mappings": [ - { - "if": "opening_hours=sunrise-sunset", - "then": { - "nl": "Van zonsopgang tot zonsondergang", - "en": "Accessible from sunrise till sunset", - "fr": "Accessible du lever au coucher du soleil", - "it": "Si può accedere dall'alba al tramonto", - "ru": "Открыто от рассвета до заката" - } - }, - { - "if": "opening_hours=24/7", - "then": { - "nl": "Dag en nacht toegankelijk", - "en": "Always accessible", - "fr": "Toujours accessible", - "ru": "Всегда доступен", - "it": "Si può sempre accedere" - } - }, - { - "if": "opening_hours=", - "then": { - "nl": "Dag en nacht toegankelijk", - "en": "Always accessible", - "ru": "Всегда доступен", - "fr": "Toujours accessible", - "it": "Si può sempre accedere" - }, - "hideInAnswer": true - } - ] - }, - "questions", - { - "render": "{reviews(name, playground)}" - } - ], - "icon": { - "render": "./assets/themes/playgrounds/playground.svg" - }, - "iconOverlays": [ - { - "if": { - "and": [ - "opening_hours!=24/7", - "opening_hours~*" + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "Speeltuin {name}", + "en": "Playground {name}", + "it": "Parco giochi {name}", + "ru": "Детская площадка {name}", + "de": "Spielplatz {name}", + "fr": "Aire de jeu {name}" + } + } ] - }, - "then": "isOpen", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "40,40,center", - "mappings": [ - { - "if": "id~node/.*", - "then": "40,40,center" - }, - { - "if": "_size_classification=small", - "then": "25,25,center" - }, - { - "if": "_size_classification=medium", - "then": "40,40,center" - }, - { - "if": "_size_classification=large", - "then": "60,60,center" - } - ] - }, - "color": { - "render": "#5dbaa9" - }, - "presets": [ - { - "tags": [ - "leisure=playground" - ], - "title": { - "nl": "Speeltuin", - "en": "Playground", - "ru": "Детская площадка", - "fr": "Terrain de jeux", - "it": "Campetto" - } - } - ], - "wayHandling": 2 + }, + "tagRenderings": [ + "images", + { + "question": { + "nl": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", + "en": "Which is the surface of this playground?
If there are multiple, select the most occuring one", + "it": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", + "de": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", + "fr": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale" + }, + "render": { + "nl": "De ondergrond is {surface}", + "en": "The surface is {surface}", + "it": "La superficie è {surface}", + "ru": "Поверхность - {surface}", + "de": "Die Oberfläche ist {surface}", + "fr": "La surface est en {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "en": "The surface is grass", + "it": "La superficie è prato", + "ru": "Поверхность - трава", + "de": "Die Oberfläche ist Gras", + "fr": "La surface est en gazon" + } + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "en": "The surface is sand", + "it": "La superficie è sabbia", + "ru": "Поверхность - песок", + "de": "Die Oberfläche ist Sand", + "fr": "La surface est en sable" + } + }, + { + "if": "surface=woodchips", + "then": { + "nl": "De ondergrond bestaat uit houtsnippers", + "en": "The surface consist of woodchips", + "it": "La superficie consiste di trucioli di legno", + "de": "Die Oberfläche besteht aus Holzschnitzeln", + "ru": "Покрытие из щепы", + "fr": "La surface est en copeaux de bois" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "en": "The surface is paving stones", + "it": "La superficie è mattonelle regolari", + "ru": "Поверхность - брусчатка", + "de": "Die Oberfläche ist Pflastersteine", + "fr": "La surface est en pavés" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "en": "The surface is asphalt", + "it": "La superficie è asfalto", + "ru": "Поверхность - асфальт", + "de": "Die Oberfläche ist Asphalt", + "fr": "La surface est en bitume" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "en": "The surface is concrete", + "it": "La superficie è cemento", + "ru": "Поверхность - бетон", + "de": "Die Oberfläche ist Beton", + "fr": "La surface est en béton" + } + }, + { + "if": "surface=unpaved", + "then": { + "nl": "De ondergrond is onverhard", + "en": "The surface is unpaved", + "it": "La superficie è non pavimentato", + "de": "Die Oberfläche ist unbefestigt", + "fr": "La surface n’a pas de revêtement" + }, + "hideInAnswer": true + }, + { + "if": "surface=paved", + "then": { + "nl": "De ondergrond is verhard", + "en": "The surface is paved", + "it": "La superficie è pavimentato", + "de": "Die Oberfläche ist befestigt", + "fr": "La surface a un revêtement" + }, + "hideInAnswer": true + } + ], + "id": "playground-surface" + }, + { + "id": "playground-lit", + "question": { + "nl": "Is deze speeltuin 's nachts verlicht?", + "en": "Is this playground lit at night?", + "it": "È illuminato di notte questo parco giochi?", + "fr": "Ce terrain de jeux est-il éclairé la nuit ?", + "de": "Ist dieser Spielplatz nachts beleuchtet?", + "ru": "Эта игровая площадка освещается ночью?" + }, + "mappings": [ + { + "if": "lit=yes", + "then": { + "nl": "Deze speeltuin is 's nachts verlicht", + "en": "This playground is lit at night", + "it": "Questo parco giochi è illuminato di notte", + "de": "Dieser Spielplatz ist nachts beleuchtet", + "ru": "Эта детская площадка освещается ночью", + "fr": "L’aire de jeu est éclairée de nuit" + } + }, + { + "if": "lit=no", + "then": { + "nl": "Deze speeltuin is 's nachts niet verlicht", + "en": "This playground is not lit at night", + "it": "Questo parco giochi non è illuminato di notte", + "de": "Dieser Spielplatz ist nachts nicht beleuchtet", + "ru": "Эта детская площадка не освещается ночью", + "fr": "L’aire de jeu n’est pas éclairée de nuit" + } + } + ] + }, + { + "render": { + "nl": "Toegankelijk vanaf {min_age} jaar oud", + "en": "Accessible to kids older than {min_age} years", + "it": "Accessibile ai bambini di almeno {min_age} anni", + "ru": "Доступно для детей старше {min_age} лет", + "fr": "Accessible aux enfants de plus de {min_age} ans" + }, + "question": { + "nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", + "en": "What is the minimum age required to access this playground?", + "it": "Qual è l’età minima per accedere a questo parco giochi?", + "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", + "ru": "С какого возраста доступна эта детская площадка?" + }, + "freeform": { + "key": "min_age", + "type": "pnat" + }, + "id": "playground-min_age" + }, + { + "render": { + "nl": "Toegankelijk tot {max_age}", + "en": "Accessible to kids of at most {max_age}", + "it": "Accessibile ai bambini di età inferiore a {max_age}", + "fr": "Accessible aux enfants de {max_age} au maximum", + "ru": "Доступно детям до {max_age}" + }, + "question": { + "nl": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", + "en": "What is the maximum age allowed to access this playground?", + "it": "Qual è l’età massima per accedere a questo parco giochi?", + "fr": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?" + }, + "freeform": { + "key": "max_age", + "type": "pnat" + }, + "id": "playground-max_age" + }, + { + "question": { + "nl": "Wie beheert deze speeltuin?", + "en": "Who operates this playground?", + "it": "Chi è il responsabile di questo parco giochi?", + "de": "Wer betreibt diesen Spielplatz?", + "fr": "Qui est en charge de l’exploitation de l’aire de jeu ?" + }, + "render": { + "nl": "Beheer door {operator}", + "en": "Operated by {operator}", + "it": "Gestito da {operator}", + "fr": "Exploité par {operator}", + "de": "Betrieben von {operator}" + }, + "freeform": { + "key": "operator" + }, + "id": "playground-operator" + }, + { + "id": "playground-access", + "question": { + "nl": "Is deze speeltuin vrij toegankelijk voor het publiek?", + "en": "Is this playground accessible to the general public?", + "it": "Questo parco giochi è pubblicamente accessibile?", + "de": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?", + "fr": "L’aire de jeu est-elle accessible au public ?" + }, + "mappings": [ + { + "if": "access=", + "then": { + "en": "Accessible to the general public", + "nl": "Vrij toegankelijk voor het publiek", + "it": "Accessibile pubblicamente", + "de": "Zugänglich für die Allgemeinheit", + "fr": "Accessible au public" + }, + "hideInAnswer": true + }, + { + "if": "access=yes", + "then": { + "en": "Accessible to the general public", + "nl": "Vrij toegankelijk voor het publiek", + "it": "Accessibile pubblicamente", + "de": "Zugänglich für die Allgemeinheit", + "fr": "Accessible au public" + } + }, + { + "if": "access=customers", + "then": { + "en": "Only accessible for clients of the operating business", + "nl": "Enkel toegankelijk voor klanten van de bijhorende zaak", + "it": "Accessibile solamente ai clienti dell’attività che lo gestisce", + "de": "Nur für Kunden des Betreibers zugänglich", + "fr": "Réservée aux clients" + } + }, + { + "if": "access=students", + "then": { + "en": "Only accessible to students of the school", + "nl": "Vrij toegankelijk voor scholieren van de school", + "it": "Accessibile solamente agli studenti della scuola", + "de": "Nur für Schüler der Schule zugänglich", + "fr": "Réservée aux élèves de l’école" + } + }, + { + "if": "access=private", + "then": { + "en": "Not accessible", + "nl": "Niet vrij toegankelijk", + "it": "Non accessibile", + "ru": "Недоступно", + "fr": "Non accessible", + "de": "Nicht zugänglich" + } + } + ] + }, + { + "question": { + "nl": "Wie kan men emailen indien er problemen zijn met de speeltuin?", + "en": "What is the email address of the playground maintainer?", + "it": "Qual è l’indirizzo email del gestore di questo parco giochi?", + "fr": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", + "de": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?" + }, + "render": { + "nl": "De bevoegde dienst kan bereikt worden via {email}", + "en": "{email}", + "ca": "{email}", + "de": "{email}", + "fr": "{email}", + "it": "{email}", + "ru": "{email}", + "id": "{email}" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "id": "playground-email" + }, + { + "question": { + "nl": "Wie kan men bellen indien er problemen zijn met de speeltuin?", + "en": "What is the phone number of the playground maintainer?", + "fr": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", + "it": "Qual è il numero di telefono del gestore del campetto?" + }, + "render": { + "nl": "De bevoegde dienst kan getelefoneerd worden via {phone}", + "en": "{phone}", + "ca": "{phone}", + "de": "{phone}", + "fr": "{phone}", + "ru": "{phone}", + "id": "{phone}", + "it": "{phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "id": "playground-phone" + }, + { + "id": "Playground-wheelchair", + "question": { + "nl": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?", + "en": "Is this playground accessible to wheelchair users?", + "fr": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?", + "de": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?", + "it": "Il campetto è accessibile a persone in sedia a rotelle?", + "ru": "Доступна ли детская площадка пользователям кресел-колясок?" + }, + "mappings": [ + { + "if": "wheelchair=yes", + "then": { + "nl": "Geheel toegankelijk voor rolstoelgebruikers", + "en": "Completely accessible for wheelchair users", + "fr": "Entièrement accessible aux personnes en fauteuil roulant", + "de": "Vollständig zugänglich für Rollstuhlfahrer", + "it": "Completamente accessibile in sedia a rotelle", + "ru": "Полностью доступна пользователям кресел-колясок" + } + }, + { + "if": "wheelchair=limited", + "then": { + "nl": "Beperkt toegankelijk voor rolstoelgebruikers", + "en": "Limited accessibility for wheelchair users", + "fr": "Accessibilité limitée pour les personnes en fauteuil roulant", + "de": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer", + "it": "Accesso limitato in sedia a rotelle", + "ru": "Частично доступна пользователям кресел-колясок" + } + }, + { + "if": "wheelchair=no", + "then": { + "nl": "Niet toegankelijk voor rolstoelgebruikers", + "en": "Not accessible for wheelchair users", + "fr": "Non accessible aux personnes en fauteuil roulant", + "de": "Nicht zugänglich für Rollstuhlfahrer", + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступна пользователям кресел-колясок" + } + } + ] + }, + { + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "render": "{opening_hours_table(opening_hours)}", + "question": { + "nl": "Op welke uren is deze speeltuin toegankelijk?", + "en": "When is this playground accessible?", + "fr": "Quand ce terrain de jeux est-il accessible ?", + "it": "Quando si può accedere a questo campetto?", + "ru": "Когда открыта эта игровая площадка?" + }, + "mappings": [ + { + "if": "opening_hours=sunrise-sunset", + "then": { + "nl": "Van zonsopgang tot zonsondergang", + "en": "Accessible from sunrise till sunset", + "fr": "Accessible du lever au coucher du soleil", + "it": "Si può accedere dall'alba al tramonto", + "ru": "Открыто от рассвета до заката" + } + }, + { + "if": "opening_hours=24/7", + "then": { + "nl": "Dag en nacht toegankelijk", + "en": "Always accessible", + "fr": "Toujours accessible", + "ru": "Всегда доступен", + "it": "Si può sempre accedere" + } + }, + { + "if": "opening_hours=", + "then": { + "nl": "Dag en nacht toegankelijk", + "en": "Always accessible", + "ru": "Всегда доступен", + "fr": "Toujours accessible", + "it": "Si può sempre accedere" + }, + "hideInAnswer": true + } + ], + "id": "playground-opening_hours" + }, + "questions", + { + "id": "playground-reviews", + "render": "{reviews(name, playground)}" + } + ], + "icon": { + "render": "./assets/themes/playgrounds/playground.svg" + }, + "iconOverlays": [ + { + "if": { + "and": [ + "opening_hours!=24/7", + "opening_hours~*" + ] + }, + "then": "isOpen", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "40,40,center", + "mappings": [ + { + "if": "id~node/.*", + "then": "40,40,center" + }, + { + "if": "_size_classification=small", + "then": "25,25,center" + }, + { + "if": "_size_classification=medium", + "then": "40,40,center" + }, + { + "if": "_size_classification=large", + "then": "60,60,center" + } + ] + }, + "color": { + "render": "#5dbaa9" + }, + "presets": [ + { + "tags": [ + "leisure=playground" + ], + "title": { + "nl": "Speeltuin", + "en": "Playground", + "ru": "Детская площадка", + "fr": "Terrain de jeux", + "it": "Campetto" + } + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 234e9d379..64b6230c1 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -1,475 +1,489 @@ { - "id": "public_bookcase", - "name": { - "en": "Bookcases", - "nl": "Boekenruilkastjes", - "de": "Bücherschränke", - "fr": "Microbibliothèque", - "ru": "Книжные шкафы", - "it": "Microbiblioteche" - }, - "description": { - "en": "A streetside cabinet with books, accessible to anyone", - "nl": "Een straatkastje met boeken voor iedereen", - "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", - "fr": "Une armoire ou une boite contenant des livres en libre accès", - "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico", - "ru": "Уличный шкаф с книгами, доступными для всех" - }, - "source": { - "osmTags": "amenity=public_bookcase" - }, - "minzoom": 12, - "wayHandling": 2, - "title": { - "render": { - "en": "Bookcase", - "nl": "Boekenruilkast", - "de": "Bücherschrank", - "fr": "Microbibliothèque", - "ru": "Книжный шкаф", - "it": "Microbiblioteca" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Public bookcase {name}", - "nl": "Boekenruilkast {name}", - "de": "Öffentlicher Bücherschrank {name}", - "fr": "Microbibliothèque {name}", - "ru": "Общественный книжный шкаф {name}", - "it": "Microbiblioteca pubblica {name}" - } - } - ] - }, - "icon": { - "render": "./assets/themes/bookcases/bookcase.svg;" - }, - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "color": { - "render": "#0000ff" - }, - "width": { - "render": "8" - }, - "presets": [ - { - "title": { - "en": "Bookcase", - "nl": "Boekenruilkast", - "de": "Bücherschrank", + "id": "public_bookcase", + "name": { + "en": "Bookcases", + "nl": "Boekenruilkastjes", + "de": "Bücherschränke", "fr": "Microbibliothèque", - "ru": "Книжный шкаф", - "it": "Microbiblioteca" - }, - "tags": [ - "amenity=public_bookcase" - ], - "preciseInput": { - "preferredBackground": "photo" - } - } - ], - "tagRenderings": [ - "images", - { - "render": "{minimap():height: 9rem; border-radius: 2.5rem; overflow:hidden;border:1px solid gray}" + "ru": "Книжные шкафы", + "it": "Microbiblioteche" }, - { - "render": { - "en": "The name of this bookcase is {name}", - "nl": "De naam van dit boekenruilkastje is {name}", - "de": "Der Name dieses Bücherschrank lautet {name}", - "fr": "Le nom de cette microbibliothèque est {name}", - "ru": "Название книжного шкафа — {name}", - "it": "Questa microbiblioteca si chiama {name}" - }, - "question": { - "en": "What is the name of this public bookcase?", - "nl": "Wat is de naam van dit boekenuilkastje?", - "de": "Wie heißt dieser öffentliche Bücherschrank?", - "fr": "Quel est le nom de cette microbibliothèque ?", - "ru": "Как называется этот общественный книжный шкаф?", - "it": "Come si chiama questa microbiblioteca pubblica?" - }, - "freeform": { - "key": "name" - }, - "mappings": [ + "description": { + "en": "A streetside cabinet with books, accessible to anyone", + "nl": "Een straatkastje met boeken voor iedereen", + "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", + "fr": "Une armoire ou une boite contenant des livres en libre accès", + "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico", + "ru": "Уличный шкаф с книгами, доступными для всех" + }, + "source": { + "osmTags": "amenity=public_bookcase" + }, + "minzoom": 10, + "wayHandling": 2, + "title": { + "render": { + "en": "Bookcase", + "nl": "Boekenruilkast", + "de": "Bücherschrank", + "fr": "Microbibliothèque", + "ru": "Книжный шкаф", + "it": "Microbiblioteca" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Public bookcase {name}", + "nl": "Boekenruilkast {name}", + "de": "Öffentlicher Bücherschrank {name}", + "fr": "Microbibliothèque {name}", + "ru": "Общественный книжный шкаф {name}", + "it": "Microbiblioteca pubblica {name}" + } + } + ] + }, + "icon": { + "render": "./assets/themes/bookcases/bookcase.svg;" + }, + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] + }, + "color": { + "render": "#0000ff" + }, + "width": { + "render": "8" + }, + "presets": [ { - "if": { + "title": { + "en": "Bookcase", + "nl": "Boekenruilkast", + "de": "Bücherschrank", + "fr": "Microbibliothèque", + "ru": "Книжный шкаф", + "it": "Microbiblioteca" + }, + "tags": [ + "amenity=public_bookcase" + ], + "preciseInput": { + "preferredBackground": "photo" + } + } + ], + "tagRenderings": [ + "images", + { + "id": "minimap", + "render": "{minimap():height: 9rem; border-radius: 2.5rem; overflow:hidden;border:1px solid gray}" + }, + { + "render": { + "en": "The name of this bookcase is {name}", + "nl": "De naam van dit boekenruilkastje is {name}", + "de": "Der Name dieses Bücherschrank lautet {name}", + "fr": "Le nom de cette microbibliothèque est {name}", + "ru": "Название книжного шкафа — {name}", + "it": "Questa microbiblioteca si chiama {name}" + }, + "question": { + "en": "What is the name of this public bookcase?", + "nl": "Wat is de naam van dit boekenuilkastje?", + "de": "Wie heißt dieser öffentliche Bücherschrank?", + "fr": "Quel est le nom de cette microbibliothèque ?", + "ru": "Как называется этот общественный книжный шкаф?", + "it": "Come si chiama questa microbiblioteca pubblica?" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": { + "and": [ + "noname=yes", + "name=" + ] + }, + "then": { + "en": "This bookcase doesn't have a name", + "nl": "Dit boekenruilkastje heeft geen naam", + "de": "Dieser Bücherschrank hat keinen Namen", + "fr": "Cette microbibliothèque n'a pas de nom", + "ru": "У этого книжного шкафа нет названия", + "it": "Questa microbiblioteca non ha un nome proprio" + } + } + ], + "id": "public_bookcase-name" + }, + { + "render": { + "en": "{capacity} books fit in this bookcase", + "nl": "Er passen {capacity} boeken", + "de": "{capacity} Bücher passen in diesen Bücherschrank", + "fr": "{capacity} livres peuvent entrer dans cette microbibliothèque", + "it": "Questa microbiblioteca può contenere fino a {capacity} libri", + "ru": "{capacity} книг помещается в этот книжный шкаф" + }, + "question": { + "en": "How many books fit into this public bookcase?", + "nl": "Hoeveel boeken passen er in dit boekenruilkastje?", + "de": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", + "fr": "Combien de livres peuvent entrer dans cette microbibliothèque ?", + "ru": "Сколько книг помещается в этом общественном книжном шкафу?", + "it": "Quanti libri può contenere questa microbiblioteca?" + }, + "freeform": { + "key": "capacity", + "type": "nat", + "inline": true + }, + "id": "public_bookcase-capacity" + }, + { + "id": "bookcase-booktypes", + "question": { + "en": "What kind of books can be found in this public bookcase?", + "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", + "de": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?", + "fr": "Quel type de livres peut-on dans cette microbibliothèque ?", + "it": "Che tipo di libri si possono trovare in questa microbiblioteca?", + "ru": "Какие книги можно найти в этом общественном книжном шкафу?" + }, + "mappings": [ + { + "if": "books=children", + "then": { + "en": "Mostly children books", + "nl": "Voornamelijk kinderboeken", + "de": "Vorwiegend Kinderbücher", + "fr": "Livres pour enfants", + "ru": "В основном детские книги", + "it": "Principalmente libri per l'infanzia" + } + }, + { + "if": "books=adults", + "then": { + "en": "Mostly books for adults", + "nl": "Voornamelijk boeken voor volwassenen", + "de": "Vorwiegend Bücher für Erwachsene", + "fr": "Livres pour les adultes", + "ru": "В основном книги для взрослых", + "it": "Principalmente libri per persone in età adulta" + } + }, + { + "if": "books=children;adults", + "then": { + "en": "Both books for kids and adults", + "nl": "Boeken voor zowel kinderen als volwassenen", + "de": "Sowohl Bücher für Kinder als auch für Erwachsene", + "fr": "Livres pour enfants et adultes également", + "it": "Sia libri per l'infanzia, sia per l'età adulta", + "ru": "Книги и для детей, и для взрослых" + } + } + ] + }, + { + "id": "bookcase-is-indoors", + "question": { + "en": "Is this bookcase located outdoors?", + "nl": "Staat dit boekenruilkastje binnen of buiten?", + "de": "Befindet sich dieser Bücherschrank im Freien?", + "fr": "Cette microbiliothèque est-elle en extérieur ?", + "it": "Questa microbiblioteca si trova all'aperto?" + }, + "mappings": [ + { + "then": { + "en": "This bookcase is located indoors", + "nl": "Dit boekenruilkastje staat binnen", + "de": "Dieser Bücherschrank befindet sich im Innenbereich", + "fr": "Cette microbibliothèque est en intérieur", + "it": "Questa microbiblioteca si trova al chiuso" + }, + "if": "indoor=yes" + }, + { + "then": { + "en": "This bookcase is located outdoors", + "nl": "Dit boekenruilkastje staat buiten", + "de": "Dieser Bücherschrank befindet sich im Freien", + "fr": "Cette microbibliothèque est en extérieur", + "it": "Questa microbiblioteca si trova all'aperto" + }, + "if": "indoor=no" + }, + { + "then": { + "en": "This bookcase is located outdoors", + "nl": "Dit boekenruilkastje staat buiten", + "de": "Dieser Bücherschrank befindet sich im Freien", + "fr": "Cette microbibliothèque est en extérieur", + "it": "Questa microbiblioteca si trova all'aperto" + }, + "if": "indoor=", + "hideInAnswer": true + } + ] + }, + { + "id": "bookcase-is-accessible", + "question": { + "en": "Is this public bookcase freely accessible?", + "nl": "Is dit boekenruilkastje publiek toegankelijk?", + "de": "Ist dieser öffentliche Bücherschrank frei zugänglich?", + "fr": "Cette microbibliothèque est-elle librement accèssible ?", + "it": "Questa microbiblioteca è ad accesso libero?", + "ru": "Имеется ли свободный доступ к этому общественному книжному шкафу?" + }, + "condition": "indoor=yes", + "mappings": [ + { + "then": { + "en": "Publicly accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "fr": "Accèssible au public", + "it": "È ad accesso libero", + "ru": "Свободный доступ" + }, + "if": "access=yes" + }, + { + "then": { + "en": "Only accessible to customers", + "nl": "Enkel toegankelijk voor klanten", + "de": "Nur für Kunden zugänglich", + "fr": "Accèssible aux clients", + "it": "L'accesso è riservato ai clienti" + }, + "if": "access=customers" + } + ] + }, + { + "question": { + "en": "Who maintains this public bookcase?", + "nl": "Wie is verantwoordelijk voor dit boekenruilkastje?", + "de": "Wer unterhält diesen öffentlichen Bücherschrank?", + "fr": "Qui entretien cette microbibliothèque ?", + "it": "Chi mantiene questa microbiblioteca?" + }, + "render": { + "en": "Operated by {operator}", + "nl": "Onderhouden door {operator}", + "de": "Betrieben von {operator}", + "fr": "Entretenue par {operator}", + "it": "È gestita da {operator}" + }, + "freeform": { + "type": "string", + "key": "operator" + }, + "id": "public_bookcase-operator" + }, + { + "question": { + "en": "Is this public bookcase part of a bigger network?", + "nl": "Is dit boekenruilkastje deel van een netwerk?", + "de": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", + "fr": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", + "it": "Questa microbiblioteca fa parte di una rete?" + }, + "render": { + "en": "This public bookcase is part of {brand}", + "nl": "Dit boekenruilkastje is deel van het netwerk {brand}", + "de": "Dieser Bücherschrank ist Teil von {brand}", + "fr": "Cette microbibliothèque fait partie du groupe {brand}", + "it": "Questa microbiblioteca fa parte di {brand}" + }, + "condition": "ref=", + "freeform": { + "key": "brand" + }, + "mappings": [ + { + "then": { + "en": "Part of the network 'Little Free Library'", + "nl": "Deel van het netwerk 'Little Free Library'", + "de": "Teil des Netzwerks 'Little Free Library'", + "fr": "Fait partie du réseau Little Free Library", + "it": "Fa parte della rete 'Little Free Library'" + }, + "if": { + "and": [ + "brand=Little Free Library", + "nobrand=" + ] + } + }, + { + "if": { + "and": [ + "nobrand=yes", + "brand=" + ] + }, + "then": { + "en": "This public bookcase is not part of a bigger network", + "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", + "de": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks", + "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", + "it": "Questa microbiblioteca non fa parte di una rete" + } + } + ], + "id": "public_bookcase-brand" + }, + { + "render": { + "en": "The reference number of this public bookcase within {brand} is {ref}", + "nl": "Het referentienummer binnen {brand} is {ref}", + "de": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}", + "fr": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}", + "it": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" + }, + "question": { + "en": "What is the reference number of this public bookcase?", + "nl": "Wat is het referentienummer van dit boekenruilkastje?", + "de": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", + "fr": "Quelle est le numéro de référence de cette microbibliothèque ?", + "it": "Qual è il numero identificativo di questa microbiblioteca?" + }, + "condition": "brand~*", + "freeform": { + "key": "ref" + }, + "mappings": [ + { + "then": { + "en": "This bookcase is not part of a bigger network", + "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", + "de": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks", + "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", + "it": "Questa microbiblioteca non fa parte di una rete" + }, + "if": { + "and": [ + "nobrand=yes", + "brand=", + "ref=" + ] + } + } + ], + "id": "public_bookcase-ref" + }, + { + "question": { + "en": "When was this public bookcase installed?", + "nl": "Op welke dag werd dit boekenruilkastje geinstalleerd?", + "de": "Wann wurde dieser öffentliche Bücherschrank installiert?", + "fr": "Quand a été installée cette microbibliothèque ?", + "it": "Quando è stata inaugurata questa microbiblioteca?", + "ru": "Когда был установлен этот общественный книжный шкаф?" + }, + "render": { + "en": "Installed on {start_date}", + "nl": "Geplaatst op {start_date}", + "de": "Installiert am {start_date}", + "fr": "Installée le {start_date}", + "it": "È stata inaugurata il {start_date}", + "ru": "Установлен {start_date}" + }, + "freeform": { + "key": "start_date", + "type": "date" + }, + "id": "public_bookcase-start_date" + }, + { + "render": { + "en": "More info on the website", + "nl": "Meer info op de website", + "de": "Weitere Informationen auf der Webseite", + "fr": "Plus d'infos sur le site web", + "ru": "Более подробная информация на сайте", + "it": "Maggiori informazioni sul sito web" + }, + "question": { + "en": "Is there a website with more information about this public bookcase?", + "nl": "Is er een website over dit boekenruilkastje?", + "de": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", + "fr": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", + "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", + "ru": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" + }, + "freeform": { + "key": "website", + "type": "url" + }, + "id": "public_bookcase-website" + } + ], + "deletion": { + "softDeletionTags": { "and": [ - "noname=yes", - "name=" + "disused:amenity=public_bookcase", + "amenity=" ] - }, - "then": { - "en": "This bookcase doesn't have a name", - "nl": "Dit boekenruilkastje heeft geen naam", - "de": "Dieser Bücherschrank hat keinen Namen", - "fr": "Cette microbibliothèque n'a pas de nom", - "ru": "У этого книжного шкафа нет названия", - "it": "Questa microbiblioteca non ha un nome proprio" - } - } - ] - }, - { - "render": { - "en": "{capacity} books fit in this bookcase", - "nl": "Er passen {capacity} boeken", - "de": "{capacity} Bücher passen in diesen Bücherschrank", - "fr": "{capacity} livres peuvent entrer dans cette microbibliothèque", - "it": "Questa microbiblioteca può contenere fino a {capacity} libri", - "ru": "{capacity} книг помещается в этот книжный шкаф" - }, - "question": { - "en": "How many books fit into this public bookcase?", - "nl": "Hoeveel boeken passen er in dit boekenruilkastje?", - "de": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", - "fr": "Combien de livres peuvent entrer dans cette microbibliothèque ?", - "ru": "Сколько книг помещается в этом общественном книжном шкафу?", - "it": "Quanti libri può contenere questa microbiblioteca?" - }, - "freeform": { - "key": "capacity", - "type": "nat", - "inline": true - } - }, - { - "question": { - "en": "What kind of books can be found in this public bookcase?", - "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", - "de": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?", - "fr": "Quel type de livres peut-on dans cette microbibliothèque ?", - "it": "Che tipo di libri si possono trovare in questa microbiblioteca?", - "ru": "Какие книги можно найти в этом общественном книжном шкафу?" - }, - "mappings": [ - { - "if": "books=children", - "then": { - "en": "Mostly children books", - "nl": "Voornamelijk kinderboeken", - "de": "Vorwiegend Kinderbücher", - "fr": "Livres pour enfants", - "ru": "В основном детские книги", - "it": "Principalmente libri per l'infanzia" - } }, - { - "if": "books=adults", - "then": { - "en": "Mostly books for adults", - "nl": "Voornamelijk boeken voor volwassenen", - "de": "Vorwiegend Bücher für Erwachsene", - "fr": "Livres pour les adultes", - "ru": "В основном книги для взрослых", - "it": "Principalmente libri per persone in età adulta" - } - }, - { - "if": "books=children;adults", - "then": { - "en": "Both books for kids and adults", - "nl": "Boeken voor zowel kinderen als volwassenen", - "de": "Sowohl Bücher für Kinder als auch für Erwachsene", - "fr": "Livres pour enfants et adultes également", - "it": "Sia libri per l'infanzia, sia per l'età adulta", - "ru": "Книги и для детей, и для взрослых" - } - } - ] + "neededChangesets": 5 }, - { - "question": { - "en": "Is this bookcase located outdoors?", - "nl": "Staat dit boekenruilkastje binnen of buiten?", - "de": "Befindet sich dieser Bücherschrank im Freien?", - "fr": "Cette microbiliothèque est-elle en extérieur ?", - "it": "Questa microbiblioteca si trova all'aperto?" - }, - "mappings": [ + "filter": [ { - "then": { - "en": "This bookcase is located indoors", - "nl": "Dit boekenruilkastje staat binnen", - "de": "Dieser Bücherschrank befindet sich im Innenbereich", - "fr": "Cette microbibliothèque est en intérieur", - "it": "Questa microbiblioteca si trova al chiuso" - }, - "if": "indoor=yes" - }, - { - "then": { - "en": "This bookcase is located outdoors", - "nl": "Dit boekenruilkastje staat buiten", - "de": "Dieser Bücherschrank befindet sich im Freien", - "fr": "Cette microbibliothèque est en extérieur", - "it": "Questa microbiblioteca si trova all'aperto" - }, - "if": "indoor=no" - }, - { - "then": { - "en": "This bookcase is located outdoors", - "nl": "Dit boekenruilkastje staat buiten", - "de": "Dieser Bücherschrank befindet sich im Freien", - "fr": "Cette microbibliothèque est en extérieur", - "it": "Questa microbiblioteca si trova all'aperto" - }, - "if": "indoor=", - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Is this public bookcase freely accessible?", - "nl": "Is dit boekenruilkastje publiek toegankelijk?", - "de": "Ist dieser öffentliche Bücherschrank frei zugänglich?", - "fr": "Cette microbibliothèque est-elle librement accèssible ?", - "it": "Questa microbiblioteca è ad accesso libero?", - "ru": "Имеется ли свободный доступ к этому общественному книжному шкафу?" - }, - "condition": "indoor=yes", - "mappings": [ - { - "then": { - "en": "Publicly accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "fr": "Accèssible au public", - "it": "È ad accesso libero", - "ru": "Свободный доступ" - }, - "if": "access=yes" - }, - { - "then": { - "en": "Only accessible to customers", - "nl": "Enkel toegankelijk voor klanten", - "de": "Nur für Kunden zugänglich", - "fr": "Accèssible aux clients", - "it": "L'accesso è riservato ai clienti" - }, - "if": "access=customers" - } - ] - }, - { - "question": { - "en": "Who maintains this public bookcase?", - "nl": "Wie is verantwoordelijk voor dit boekenruilkastje?", - "de": "Wer unterhält diesen öffentlichen Bücherschrank?", - "fr": "Qui entretien cette microbibliothèque ?", - "it": "Chi mantiene questa microbiblioteca?" - }, - "render": { - "en": "Operated by {operator}", - "nl": "Onderhouden door {operator}", - "de": "Betrieben von {operator}", - "fr": "Entretenue par {operator}", - "it": "È gestita da {operator}" - }, - "freeform": { - "type": "string", - "key": "operator" - } - }, - { - "question": { - "en": "Is this public bookcase part of a bigger network?", - "nl": "Is dit boekenruilkastje deel van een netwerk?", - "de": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", - "fr": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", - "it": "Questa microbiblioteca fa parte di una rete?" - }, - "render": { - "en": "This public bookcase is part of {brand}", - "nl": "Dit boekenruilkastje is deel van het netwerk {brand}", - "de": "Dieser Bücherschrank ist Teil von {brand}", - "fr": "Cette microbibliothèque fait partie du groupe {brand}", - "it": "Questa microbiblioteca fa parte di {brand}" - }, - "condition": "ref=", - "freeform": { - "key": "brand" - }, - "mappings": [ - { - "then": { - "en": "Part of the network 'Little Free Library'", - "nl": "Deel van het netwerk 'Little Free Library'", - "de": "Teil des Netzwerks 'Little Free Library'", - "fr": "Fait partie du réseau Little Free Library", - "it": "Fa parte della rete 'Little Free Library'" - }, - "if": { - "and": [ - "brand=Little Free Library", - "nobrand=" + "id": "kid-books", + "options": [ + { + "question": "Kinderboeken aanwezig?", + "osmTags": "books~.*children.*" + } ] - } }, { - "if": { - "and": [ - "nobrand=yes", - "brand=" + "id": "adult-books", + "options": [ + { + "question": "Boeken voor volwassenen aanwezig?", + "osmTags": "books~.*adults.*" + } ] - }, - "then": { - "en": "This public bookcase is not part of a bigger network", - "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", - "de": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks", - "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", - "it": "Questa microbiblioteca non fa parte di una rete" - } - } - ] - }, - { - "render": { - "en": "The reference number of this public bookcase within {brand} is {ref}", - "nl": "Het referentienummer binnen {brand} is {ref}", - "de": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}", - "fr": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}", - "it": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" - }, - "question": { - "en": "What is the reference number of this public bookcase?", - "nl": "Wat is het referentienummer van dit boekenruilkastje?", - "de": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", - "fr": "Quelle est le numéro de référence de cette microbibliothèque ?", - "it": "Qual è il numero identificativo di questa microbiblioteca?" - }, - "condition": "brand~*", - "freeform": { - "key": "ref" - }, - "mappings": [ - { - "then": { - "en": "This bookcase is not part of a bigger network", - "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", - "de": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks", - "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", - "it": "Questa microbiblioteca non fa parte di una rete" - }, - "if": { - "and": [ - "nobrand=yes", - "brand=", - "ref=" - ] - } - } - ] - }, - { - "question": { - "en": "When was this public bookcase installed?", - "nl": "Op welke dag werd dit boekenruilkastje geinstalleerd?", - "de": "Wann wurde dieser öffentliche Bücherschrank installiert?", - "fr": "Quand a été installée cette microbibliothèque ?", - "it": "Quando è stata inaugurata questa microbiblioteca?", - "ru": "Когда был установлен этот общественный книжный шкаф?" - }, - "render": { - "en": "Installed on {start_date}", - "nl": "Geplaatst op {start_date}", - "de": "Installiert am {start_date}", - "fr": "Installée le {start_date}", - "it": "È stata inaugurata il {start_date}", - "ru": "Установлен {start_date}" - }, - "freeform": { - "key": "start_date", - "type": "date" - } - }, - { - "render": { - "en": "More info on the website", - "nl": "Meer info op de website", - "de": "Weitere Informationen auf der Webseite", - "fr": "Plus d'infos sur le site web", - "ru": "Более подробная информация на сайте", - "it": "Maggiori informazioni sul sito web" - }, - "question": { - "en": "Is there a website with more information about this public bookcase?", - "nl": "Is er een website over dit boekenruilkastje?", - "de": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", - "fr": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", - "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", - "ru": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" - }, - "freeform": { - "key": "website", - "type": "url" - } - } - ], - "deletion": { - "softDeletionTags": { - "and": [ - "disused:amenity=public_bookcase", - "amenity=" - ] - }, - "neededChangesets": 5 - }, - "filter": [ - { - "options": [ - { - "question": "Kinderboeken aanwezig?", - "osmTags": "books~.*children.*" - } - ] - }, - { - "options": [ - { - "question": "Boeken voor volwassenen aanwezig?", - "osmTags": "books~.*adults.*" - } - ] - }, - { - "options": [ - { - "question": "Binnen of buiten", - "osmTags": { - "and": [] - } }, { - "question": "Binnen?", - "osmTags": "indoor=yes" - }, - { - "question": "Buiten?", - "osmTags": { - "or": [ - "indoor=no", - "indoor=" + "id": "inside", + "options": [ + { + "question": { + "nl": "Binnen of buiten", + "en": "Indoor or outdoor" + } + }, + { + "question": "Binnen?", + "osmTags": "indoor=yes" + }, + { + "question": "Buiten?", + "osmTags": { + "or": [ + "indoor=no", + "indoor=" + ] + } + } ] - } } - ] - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json index 2afbca07f..50e7cd61d 100644 --- a/assets/layers/slow_roads/slow_roads.json +++ b/assets/layers/slow_roads/slow_roads.json @@ -1,253 +1,256 @@ { - "id": "slow_roads", - "name": { - "nl": "Paadjes, trage wegen en autoluwe straten" - }, - "icon": "./assets/layers/slow_roads/slow_road.svg", - "minzoom": 16, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "highway=pedestrian", - "highway=footway", - "highway=path", - "highway=bridleway", - "highway=living_street", - "highway=track" - ] - }, - "access!=no", - "access!=private" - ] - } - }, - "title": { - "render": { - "nl": "Trage weg" + "id": "slow_roads", + "name": { + "nl": "Paadjes, trage wegen en autoluwe straten" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "icon": "./assets/layers/slow_roads/slow_road.svg", + "minzoom": 16, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "highway=pedestrian", + "highway=footway", + "highway=path", + "highway=bridleway", + "highway=living_street", + "highway=track" + ] + }, + "access!=no", + "access!=private" + ] } - }, - { - "if": "highway=footway", - "then": { - "nl": "Voetpad" - } - }, - { - "if": "highway=cycleway", - "then": { - "nl": "Fietspad" - } - }, - { - "if": "highway=pedestrian", - "then": { - "nl": "Voetgangersstraat" - } - }, - { - "if": "highway=living_street", - "then": { - "nl": "Woonerf" - } - }, - { - "if": "highway=path", - "then": "Klein pad" - } - ] - }, - "tagRenderings": [ - "images", - { - "mappings": [ - { - "if": "highway=living_street", - "then": { - "nl:": "
Dit is een woonerf:
  • Voetgangers mogen hier de volledige breedte van de straat gebruiken
  • Gemotoriseerd verkeer mag maximaal 20km/h rijden
" - } - }, - { - "if": "highway=pedestrian", - "then": { - "nl": "Dit is een brede, autovrije straat" - } - }, - { - "if": "highway=footway", - "then": { - "nl": "Dit is een voetpaadje" - } - }, - { - "if": "highway=path", - "then": { - "nl": "Dit is een wegeltje of bospad" - } - }, - { - "if": "highway=bridleway", - "then": { - "nl": "Dit is een ruiterswegel" - } - }, - { - "if": "highway=track", - "then": { - "nl": "Dit is een tractorspoor of weg om landbouwgrond te bereikken" - } - } - ] }, - { - "question": { - "nl": "Wat is de wegverharding van dit pad?" - }, - "render": { - "nl": "De ondergrond is {surface}", - "en": "The surface is {surface}", - "ru": "Поверхность - {surface}", - "fr": "La surface en {surface}", - "it": "La superficie è {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "en": "The surface is grass", - "ru": "Поверхность - трава", - "fr": "La surface est en herbe", - "it": "La superficie è erba" - } + "title": { + "render": { + "nl": "Trage weg" }, - { - "if": "surface=ground", - "then": { - "nl": "De ondergrond is aarde", - "en": "The surface is ground", - "ru": "Поверхность - земля", - "fr": "La surface est en terre", - "it": "La superficie è terreno" - } - }, - { - "if": "surface=unpaved", - "then": { - "nl": "De ondergrond is onverhard", - "en": "The surface is unpaved", - "fr": "La surface est non pavée", - "it": "La superficie è non pavimentata" - }, - "hideInAnswer": true - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "en": "The surface is sand", - "ru": "Поверхность - песок", - "fr": "La surface est en sable", - "it": "La superficie è sabbia" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "en": "The surface is paving stones", - "ru": "Поверхность - брусчатка", - "it": "La superficie è pietre irregolari", - "fr": "La surface est en pierres pavées" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "en": "The surface is asphalt", - "ru": "Поверхность - асфальт", - "it": "La superficie è asfalto", - "fr": "La surface est en bitume" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "en": "The surface is concrete", - "ru": "Поверхность - бетон", - "fr": "La surface est en béton", - "it": "La superficie è calcestruzzo" - } - }, - { - "if": "surface=paved", - "then": { - "nl": "De ondergrond is verhard", - "en": "The surface is paved", - "fr": "La surface est pavée", - "it": "La superficie è pavimentata" - }, - "hideInAnswer": true - } - ] + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + }, + { + "if": "highway=footway", + "then": { + "nl": "Voetpad" + } + }, + { + "if": "highway=cycleway", + "then": { + "nl": "Fietspad" + } + }, + { + "if": "highway=pedestrian", + "then": { + "nl": "Voetgangersstraat" + } + }, + { + "if": "highway=living_street", + "then": { + "nl": "Woonerf" + } + }, + { + "if": "highway=path", + "then": "Klein pad" + } + ] }, - { - "question": "Is deze weg 's nachts verlicht?", - "mappings": [ + "tagRenderings": [ + "images", { - "if": "lit=yes", - "then": "'s nachts verlicht" + "id": "explanation", + "mappings": [ + { + "if": "highway=living_street", + "then": { + "nl:": "
Dit is een woonerf:
  • Voetgangers mogen hier de volledige breedte van de straat gebruiken
  • Gemotoriseerd verkeer mag maximaal 20km/h rijden
" + } + }, + { + "if": "highway=pedestrian", + "then": { + "nl": "Dit is een brede, autovrije straat" + } + }, + { + "if": "highway=footway", + "then": { + "nl": "Dit is een voetpaadje" + } + }, + { + "if": "highway=path", + "then": { + "nl": "Dit is een wegeltje of bospad" + } + }, + { + "if": "highway=bridleway", + "then": { + "nl": "Dit is een ruiterswegel" + } + }, + { + "if": "highway=track", + "then": { + "nl": "Dit is een tractorspoor of weg om landbouwgrond te bereikken" + } + } + ] }, { - "if": "lit=no", - "then": "Niet verlicht" + "question": { + "nl": "Wat is de wegverharding van dit pad?" + }, + "render": { + "nl": "De ondergrond is {surface}", + "en": "The surface is {surface}", + "ru": "Поверхность - {surface}", + "fr": "La surface en {surface}", + "it": "La superficie è {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "en": "The surface is grass", + "ru": "Поверхность - трава", + "fr": "La surface est en herbe", + "it": "La superficie è erba" + } + }, + { + "if": "surface=ground", + "then": { + "nl": "De ondergrond is aarde", + "en": "The surface is ground", + "ru": "Поверхность - земля", + "fr": "La surface est en terre", + "it": "La superficie è terreno" + } + }, + { + "if": "surface=unpaved", + "then": { + "nl": "De ondergrond is onverhard", + "en": "The surface is unpaved", + "fr": "La surface est non pavée", + "it": "La superficie è non pavimentata" + }, + "hideInAnswer": true + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "en": "The surface is sand", + "ru": "Поверхность - песок", + "fr": "La surface est en sable", + "it": "La superficie è sabbia" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "en": "The surface is paving stones", + "ru": "Поверхность - брусчатка", + "it": "La superficie è pietre irregolari", + "fr": "La surface est en pierres pavées" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "en": "The surface is asphalt", + "ru": "Поверхность - асфальт", + "it": "La superficie è asfalto", + "fr": "La surface est en bitume" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "en": "The surface is concrete", + "ru": "Поверхность - бетон", + "fr": "La surface est en béton", + "it": "La superficie è calcestruzzo" + } + }, + { + "if": "surface=paved", + "then": { + "nl": "De ondergrond is verhard", + "en": "The surface is paved", + "fr": "La surface est pavée", + "it": "La superficie è pavimentata" + }, + "hideInAnswer": true + } + ], + "id": "slow_roads-surface" + }, + { + "id": "slow_road_is_lit", + "question": "Is deze weg 's nachts verlicht?", + "mappings": [ + { + "if": "lit=yes", + "then": "'s nachts verlicht" + }, + { + "if": "lit=no", + "then": "Niet verlicht" + } + ] } - ] - } - ], - "width": { - "render": "7" - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": "highway=cycleway", - "then": "" - }, - { - "if": "highway=path", - "then": "0 12" - }, - { - "if": { - "or": [ - "highway=footway", - "highway=pedestrian" - ] - }, - "then": "12 18" - }, - { - "if": "highway=living_street", - "then": "12 12 0 12" - } - ] - }, - "color": { - "render": "#eaba2a" - }, - "presets": [] + ], + "width": { + "render": "7" + }, + "dashArray": { + "render": "", + "mappings": [ + { + "if": "highway=cycleway", + "then": "" + }, + { + "if": "highway=path", + "then": "0 12" + }, + { + "if": { + "or": [ + "highway=footway", + "highway=pedestrian" + ] + }, + "then": "12 18" + }, + { + "if": "highway=living_street", + "then": "12 12 0 12" + } + ] + }, + "color": { + "render": "#eaba2a" + }, + "presets": [] } \ No newline at end of file diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index b871523f7..90f1dca73 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -1,486 +1,494 @@ { - "id": "sport_pitch", - "name": { - "nl": "Sportterrein", - "fr": "Terrains de sport", - "en": "Sport pitches", - "ru": "Спортивные площадки", - "it": "Campi sportivi" - }, - "wayHandling": 1, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "leisure=pitch" - ] - } - }, - "calculatedTags": [ - "_size_classification=Number(feat.properties._surface) < 200 ? 'small' : (Number(feat.properties._surface) < 750 ? 'medium' : 'large') " - ], - "title": { - "render": { - "nl": "Sportterrein", - "fr": "Terrain de sport", - "en": "Sport pitch", - "ru": "Спортивная площадка", - "it": "Campo sportivo" - } - }, - "description": { - "nl": "Een sportterrein", - "fr": "Un terrain de sport", - "en": "A sport pitch", - "it": "Un campo sportivo", - "ru": "Спортивная площадка" - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "Hier kan men {sport} beoefenen", - "fr": "Ici on joue au {sport}", - "en": "{sport} is played here", - "it": "Qui si gioca a {sport}" - }, - "freeform": { - "key": "sport" - }, - "question": { - "nl": "Welke sporten kan men hier beoefenen?", - "fr": "À quel sport peut-on jouer ici ?", - "en": "Which sport can be played here?", - "it": "Quale sport si gioca qui?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": { - "and": [ - "sport=basketball" - ] - }, - "then": { - "nl": "Hier kan men basketbal spelen", - "fr": "Ici, on joue au basketball", - "en": "Basketball is played here", - "it": "Qui si gioca a basket", - "ru": "Здесь можно играть в баскетбол" - } - }, - { - "if": { - "and": [ - "sport=soccer" - ] - }, - "then": { - "nl": "Hier kan men voetbal spelen", - "fr": "Ici, on joue au football", - "en": "Soccer is played here", - "it": "Qui si gioca a calcio", - "ru": "Здесь можно играть в футбол" - } - }, - { - "if": { - "and": [ - "sport=table_tennis" - ] - }, - "then": { - "nl": "Dit is een pingpongtafel", - "fr": "C'est une table de ping-pong", - "en": "This is a pingpong table", - "ru": "Это стол для пинг-понга", - "it": "Questo è un tavolo da ping pong" - } - }, - { - "if": { - "and": [ - "sport=tennis" - ] - }, - "then": { - "nl": "Hier kan men tennis spelen", - "fr": "Ici, on joue au tennis", - "en": "Tennis is played here", - "it": "Qui si gioca a tennis", - "ru": "Здесь можно играть в теннис" - } - }, - { - "if": { - "and": [ - "sport=korfball" - ] - }, - "then": { - "nl": "Hier kan men korfbal spelen", - "fr": "Ici, on joue au korfball", - "en": "Korfball is played here", - "it": "Qui si gioca a korfball", - "ru": "Здесь можно играть в корфбол" - } - }, - { - "if": { - "and": [ - "sport=basket" - ] - }, - "then": { - "nl": "Hier kan men basketbal beoefenen", - "fr": "Ici, on joue au basketball", - "en": "Basketball is played here", - "it": "Qui si gioca a basket", - "ru": "Здесь можно играть в баскетбол" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Wat is de ondergrond van dit sportveld?", - "fr": "De quelle surface est fait ce terrain de sport ?", - "en": "Which is the surface of this sport pitch?", - "it": "Qual è la superficie di questo campo sportivo?", - "ru": "Какое покрытие на этой спортивной площадке?" - }, - "render": { - "nl": "De ondergrond is {surface}", - "fr": "La surface est {surface}", - "en": "The surface is {surface}", - "ru": "Поверхность - {surface}", - "it": "La superficie è {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "fr": "La surface est de l'herbe", - "en": "The surface is grass", - "ru": "Поверхность - трава", - "it": "La superficie è erba" - } - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "fr": "La surface est du sable", - "en": "The surface is sand", - "ru": "Поверхность - песок", - "it": "La superficie è sabbia" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "fr": "La surface est des pavés", - "en": "The surface is paving stones", - "ru": "Поверхность - брусчатка", - "it": "La superficie è pietre irregolari" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "fr": "La surface est de l'asphalte", - "en": "The surface is asphalt", - "ru": "Поверхность - асфальт", - "it": "La superficie è asfalto" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "fr": "La surface est du béton", - "en": "The surface is concrete", - "ru": "Поверхность - бетон", - "it": "La superficie è calcestruzzo" - } - } - ] - }, - { - "question": { - "nl": "Is dit sportterrein publiek toegankelijk?", - "fr": "Est-ce que ce terrain de sport est accessible au public ?", - "en": "Is this sport pitch publicly accessible?", - "it": "Questo campo sportivo è aperto al pubblico?", - "ru": "Есть ли свободный доступ к этой спортивной площадке?" - }, - "mappings": [ - { - "if": "access=public", - "then": { - "nl": "Publiek toegankelijk", - "fr": "Accessible au public", - "en": "Public access", - "it": "Aperto al pubblico", - "ru": "Свободный доступ" - } - }, - { - "if": "access=limited", - "then": { - "nl": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)", - "fr": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)", - "en": "Limited access (e.g. only with an appointment, during certain hours, ...)", - "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)", - "ru": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" - } - }, - { - "if": "access=members", - "then": { - "nl": "Enkel toegankelijk voor leden van de bijhorende sportclub", - "fr": "Accessible uniquement aux membres du club", - "en": "Only accessible for members of the club", - "it": "Accesso limitato ai membri dell'associazione", - "ru": "Доступ только членам клуба" - } - }, - { - "if": "access=private", - "then": { - "nl": "Privaat en niet toegankelijk", - "fr": "Privé - Pas accessible au public", - "en": "Private - not accessible to the public", - "it": "Privato - non aperto al pubblico" - } - } - ] - }, - { - "question": { - "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", - "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", - "en": "Does one have to make an appointment to use this sport pitch?", - "it": "È necessario prenotarsi per usare questo campo sportivo?", - "ru": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" - }, - "condition": { - "and": [ - "access!=public", - "access!=private", - "access!=members" - ] - }, - "mappings": [ - { - "if": "reservation=required", - "then": { - "nl": "Reserveren is verplicht om gebruik te maken van dit sportterrein", - "fr": "Il est obligatoire de réserver pour utiliser ce terrain de sport", - "en": "Making an appointment is obligatory to use this sport pitch", - "it": "La prenotazione è obbligatoria per usare questo campo sportivo" - } - }, - { - "if": "reservation=recommended", - "then": { - "nl": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein", - "fr": "Il est recommendé de réserver pour utiliser ce terrain de sport", - "en": "Making an appointment is recommended when using this sport pitch", - "it": "La prenotazione è consigliata per usare questo campo sportivo", - "ru": "Желательна предварительная запись для доступа на эту спортивную площадку" - } - }, - { - "if": "reservation=yes", - "then": { - "nl": "Reserveren is mogelijk, maar geen voorwaarde", - "fr": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport", - "en": "Making an appointment is possible, but not necessary to use this sport pitch", - "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo", - "ru": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" - } - }, - { - "if": "reservation=no", - "then": { - "nl": "Reserveren is niet mogelijk", - "fr": "On ne peut pas réserver", - "en": "Making an appointment is not possible", - "it": "Non è possibile prenotare", - "ru": "Невозможна предварительная запись" - } - } - ] - }, - { - "question": { - "nl": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?", - "fr": "Quel est le numéro de téléphone du gérant ?", - "en": "What is the phone number of the operator?", - "it": "Qual è il numero di telefono del gestore?" - }, - "freeform": { - "key": "phone", - "type": "phone" - }, - "render": "{phone}" - }, - { - "question": { - "nl": "Wat is het email-adres van de bevoegde dienst of uitbater?", - "fr": "Quelle est l'adresse courriel du gérant ?", - "en": "What is the email address of the operator?", - "it": "Qual è l'indirizzo email del gestore?" - }, - "freeform": { - "key": "email", - "type": "email" - }, - "render": "{email}" - }, - { - "question": { - "nl": "Wanneer is dit sportveld toegankelijk?", - "fr": "Quand ce terrain est-il accessible ?", - "en": "When is this pitch accessible?", - "it": "Quando è aperto questo campo sportivo?", - "ru": "В какое время доступна эта площадка?" - }, - "render": "Openingsuren: {opening_hours_table()}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=", - "then": "24/7 toegankelijk", - "hideInAnswer": true - }, - { - "if": "opening_hours=24/7", - "then": { - "nl": "24/7 toegankelijk", - "fr": "Accessible en permanence", - "en": "Always accessible", - "ru": "Всегда доступен", - "it": "Sempre aperto" - } - } - ], - "condition": "access~*" - }, - "questions", - { - "render": "{reviews(name, sportpitch)}" - } - ], - "icon": { - "render": "circle:white;./assets/layers/sport_pitch/sport_pitch.svg", - "mappings": [ - { - "if": { - "or": [ - "sport=baseball", - "sport=basketball", - "sport=beachvolleyball", - "sport=boules", - "sport=skateboard", - "sport=soccer", - "sport=table_tennis", - "sport=tennis", - "sport=volleyball" - ] - }, - "then": "circle:white;./assets/layers/sport_pitch/{sport}.svg" - } - ] - }, - "iconOverlays": [ - { - "if": { - "and": [ - "opening_hours!=24/7", - "opening_hours~*" - ] - }, - "then": "isOpen", - "badge": true - }, - { - "if": { - "or": [ - "access=customers", - "access=private", - "access=no" - ] - }, - "then": "circle:white;./assets/layers/sport_pitch/lock.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "25,25,center", - "mappings": [ - { - "if": { - "or": [ - "_size_classification=medium", - "id~node/.*" - ] - }, - "then": "40,40,center" - }, - { - "if": "_size_classification=small", - "then": "25,25,center" - }, - { - "if": "_size_classification=large", - "then": "50,50,center" - } - ] - }, - "color": { - "render": "#7cb82f" - }, - "presets": [ - { - "title": { - "nl": "Ping-pong tafel", - "fr": "Table de ping-pong", - "en": "Tabletennis table", - "it": "Tavolo da tennistavolo", - "ru": "Стол для настольного тенниса" - }, - "tags": [ - "leisure=pitch", - "sport=table_tennis" - ] - }, - { - "title": { + "id": "sport_pitch", + "name": { "nl": "Sportterrein", - "fr": "Terrain de sport", - "en": "Sport pitch", - "ru": "Спортивная площадка", - "it": "Campo sportivo" - }, - "tags": [ - "leisure=pitch", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ] - } - ] + "fr": "Terrains de sport", + "en": "Sport pitches", + "ru": "Спортивные площадки", + "it": "Campi sportivi" + }, + "wayHandling": 1, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "leisure=pitch" + ] + } + }, + "calculatedTags": [ + "_size_classification=Number(feat.properties._surface) < 200 ? 'small' : (Number(feat.properties._surface) < 750 ? 'medium' : 'large') " + ], + "title": { + "render": { + "nl": "Sportterrein", + "fr": "Terrain de sport", + "en": "Sport pitch", + "ru": "Спортивная площадка", + "it": "Campo sportivo" + } + }, + "description": { + "nl": "Een sportterrein", + "fr": "Un terrain de sport", + "en": "A sport pitch", + "it": "Un campo sportivo", + "ru": "Спортивная площадка" + }, + "tagRenderings": [ + "images", + { + "render": { + "nl": "Hier kan men {sport} beoefenen", + "fr": "Ici on joue au {sport}", + "en": "{sport} is played here", + "it": "Qui si gioca a {sport}" + }, + "freeform": { + "key": "sport" + }, + "question": { + "nl": "Welke sporten kan men hier beoefenen?", + "fr": "À quel sport peut-on jouer ici ?", + "en": "Which sport can be played here?", + "it": "Quale sport si gioca qui?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": { + "and": [ + "sport=basketball" + ] + }, + "then": { + "nl": "Hier kan men basketbal spelen", + "fr": "Ici, on joue au basketball", + "en": "Basketball is played here", + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" + } + }, + { + "if": { + "and": [ + "sport=soccer" + ] + }, + "then": { + "nl": "Hier kan men voetbal spelen", + "fr": "Ici, on joue au football", + "en": "Soccer is played here", + "it": "Qui si gioca a calcio", + "ru": "Здесь можно играть в футбол" + } + }, + { + "if": { + "and": [ + "sport=table_tennis" + ] + }, + "then": { + "nl": "Dit is een pingpongtafel", + "fr": "C'est une table de ping-pong", + "en": "This is a pingpong table", + "ru": "Это стол для пинг-понга", + "it": "Questo è un tavolo da ping pong" + } + }, + { + "if": { + "and": [ + "sport=tennis" + ] + }, + "then": { + "nl": "Hier kan men tennis spelen", + "fr": "Ici, on joue au tennis", + "en": "Tennis is played here", + "it": "Qui si gioca a tennis", + "ru": "Здесь можно играть в теннис" + } + }, + { + "if": { + "and": [ + "sport=korfball" + ] + }, + "then": { + "nl": "Hier kan men korfbal spelen", + "fr": "Ici, on joue au korfball", + "en": "Korfball is played here", + "it": "Qui si gioca a korfball", + "ru": "Здесь можно играть в корфбол" + } + }, + { + "if": { + "and": [ + "sport=basket" + ] + }, + "then": { + "nl": "Hier kan men basketbal beoefenen", + "fr": "Ici, on joue au basketball", + "en": "Basketball is played here", + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" + }, + "hideInAnswer": true + } + ], + "id": "sport_pitch-sport" + }, + { + "question": { + "nl": "Wat is de ondergrond van dit sportveld?", + "fr": "De quelle surface est fait ce terrain de sport ?", + "en": "Which is the surface of this sport pitch?", + "it": "Qual è la superficie di questo campo sportivo?", + "ru": "Какое покрытие на этой спортивной площадке?" + }, + "render": { + "nl": "De ondergrond is {surface}", + "fr": "La surface est {surface}", + "en": "The surface is {surface}", + "ru": "Поверхность - {surface}", + "it": "La superficie è {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "fr": "La surface est de l'herbe", + "en": "The surface is grass", + "ru": "Поверхность - трава", + "it": "La superficie è erba" + } + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "fr": "La surface est du sable", + "en": "The surface is sand", + "ru": "Поверхность - песок", + "it": "La superficie è sabbia" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "fr": "La surface est des pavés", + "en": "The surface is paving stones", + "ru": "Поверхность - брусчатка", + "it": "La superficie è pietre irregolari" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "fr": "La surface est de l'asphalte", + "en": "The surface is asphalt", + "ru": "Поверхность - асфальт", + "it": "La superficie è asfalto" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "fr": "La surface est du béton", + "en": "The surface is concrete", + "ru": "Поверхность - бетон", + "it": "La superficie è calcestruzzo" + } + } + ], + "id": "sport_pitch-surface" + }, + { + "id": "sport-pitch-access", + "question": { + "nl": "Is dit sportterrein publiek toegankelijk?", + "fr": "Est-ce que ce terrain de sport est accessible au public ?", + "en": "Is this sport pitch publicly accessible?", + "it": "Questo campo sportivo è aperto al pubblico?", + "ru": "Есть ли свободный доступ к этой спортивной площадке?" + }, + "mappings": [ + { + "if": "access=public", + "then": { + "nl": "Publiek toegankelijk", + "fr": "Accessible au public", + "en": "Public access", + "it": "Aperto al pubblico", + "ru": "Свободный доступ" + } + }, + { + "if": "access=limited", + "then": { + "nl": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)", + "fr": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)", + "en": "Limited access (e.g. only with an appointment, during certain hours, ...)", + "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)", + "ru": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" + } + }, + { + "if": "access=members", + "then": { + "nl": "Enkel toegankelijk voor leden van de bijhorende sportclub", + "fr": "Accessible uniquement aux membres du club", + "en": "Only accessible for members of the club", + "it": "Accesso limitato ai membri dell'associazione", + "ru": "Доступ только членам клуба" + } + }, + { + "if": "access=private", + "then": { + "nl": "Privaat en niet toegankelijk", + "fr": "Privé - Pas accessible au public", + "en": "Private - not accessible to the public", + "it": "Privato - non aperto al pubblico" + } + } + ] + }, + { + "id": "sport-pitch-reservation", + "question": { + "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", + "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", + "en": "Does one have to make an appointment to use this sport pitch?", + "it": "È necessario prenotarsi per usare questo campo sportivo?", + "ru": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" + }, + "condition": { + "and": [ + "access!=public", + "access!=private", + "access!=members" + ] + }, + "mappings": [ + { + "if": "reservation=required", + "then": { + "nl": "Reserveren is verplicht om gebruik te maken van dit sportterrein", + "fr": "Il est obligatoire de réserver pour utiliser ce terrain de sport", + "en": "Making an appointment is obligatory to use this sport pitch", + "it": "La prenotazione è obbligatoria per usare questo campo sportivo" + } + }, + { + "if": "reservation=recommended", + "then": { + "nl": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein", + "fr": "Il est recommendé de réserver pour utiliser ce terrain de sport", + "en": "Making an appointment is recommended when using this sport pitch", + "it": "La prenotazione è consigliata per usare questo campo sportivo", + "ru": "Желательна предварительная запись для доступа на эту спортивную площадку" + } + }, + { + "if": "reservation=yes", + "then": { + "nl": "Reserveren is mogelijk, maar geen voorwaarde", + "fr": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport", + "en": "Making an appointment is possible, but not necessary to use this sport pitch", + "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo", + "ru": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" + } + }, + { + "if": "reservation=no", + "then": { + "nl": "Reserveren is niet mogelijk", + "fr": "On ne peut pas réserver", + "en": "Making an appointment is not possible", + "it": "Non è possibile prenotare", + "ru": "Невозможна предварительная запись" + } + } + ] + }, + { + "question": { + "nl": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?", + "fr": "Quel est le numéro de téléphone du gérant ?", + "en": "What is the phone number of the operator?", + "it": "Qual è il numero di telefono del gestore?" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "render": "{phone}", + "id": "sport_pitch-phone" + }, + { + "question": { + "nl": "Wat is het email-adres van de bevoegde dienst of uitbater?", + "fr": "Quelle est l'adresse courriel du gérant ?", + "en": "What is the email address of the operator?", + "it": "Qual è l'indirizzo email del gestore?" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "render": "{email}", + "id": "sport_pitch-email" + }, + { + "question": { + "nl": "Wanneer is dit sportveld toegankelijk?", + "fr": "Quand ce terrain est-il accessible ?", + "en": "When is this pitch accessible?", + "it": "Quando è aperto questo campo sportivo?", + "ru": "В какое время доступна эта площадка?" + }, + "render": "Openingsuren: {opening_hours_table()}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=", + "then": "24/7 toegankelijk", + "hideInAnswer": true + }, + { + "if": "opening_hours=24/7", + "then": { + "nl": "24/7 toegankelijk", + "fr": "Accessible en permanence", + "en": "Always accessible", + "ru": "Всегда доступен", + "it": "Sempre aperto" + } + } + ], + "condition": "access~*", + "id": "sport_pitch-opening_hours" + }, + "questions", + { + "id": "sport-pitch-reviews", + "render": "{reviews(name, sportpitch)}" + } + ], + "icon": { + "render": "circle:white;./assets/layers/sport_pitch/sport_pitch.svg", + "mappings": [ + { + "if": { + "or": [ + "sport=baseball", + "sport=basketball", + "sport=beachvolleyball", + "sport=boules", + "sport=skateboard", + "sport=soccer", + "sport=table_tennis", + "sport=tennis", + "sport=volleyball" + ] + }, + "then": "circle:white;./assets/layers/sport_pitch/{sport}.svg" + } + ] + }, + "iconOverlays": [ + { + "if": { + "and": [ + "opening_hours!=24/7", + "opening_hours~*" + ] + }, + "then": "isOpen", + "badge": true + }, + { + "if": { + "or": [ + "access=customers", + "access=private", + "access=no" + ] + }, + "then": "circle:white;./assets/layers/sport_pitch/lock.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "25,25,center", + "mappings": [ + { + "if": { + "or": [ + "_size_classification=medium", + "id~node/.*" + ] + }, + "then": "40,40,center" + }, + { + "if": "_size_classification=small", + "then": "25,25,center" + }, + { + "if": "_size_classification=large", + "then": "50,50,center" + } + ] + }, + "color": { + "render": "#7cb82f" + }, + "presets": [ + { + "title": { + "nl": "Ping-pong tafel", + "fr": "Table de ping-pong", + "en": "Tabletennis table", + "it": "Tavolo da tennistavolo", + "ru": "Стол для настольного тенниса" + }, + "tags": [ + "leisure=pitch", + "sport=table_tennis" + ] + }, + { + "title": { + "nl": "Sportterrein", + "fr": "Terrain de sport", + "en": "Sport pitch", + "ru": "Спортивная площадка", + "it": "Campo sportivo" + }, + "tags": [ + "leisure=pitch", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/surveillance_camera/surveillance_camera.json b/assets/layers/surveillance_camera/surveillance_camera.json index 7a6a4248c..7472ffd80 100644 --- a/assets/layers/surveillance_camera/surveillance_camera.json +++ b/assets/layers/surveillance_camera/surveillance_camera.json @@ -1,484 +1,484 @@ { - "id": "surveillance_camera", - "name": { - "en": "Surveillance camera's", - "nl": "Bewakingscamera's", - "ru": "Камеры наблюдения", - "fr": "Caméras de surveillance", - "it": "Videocamere di sorveglianza" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=surveillance", - { - "or": [ - "surveillance:type=camera", - "surveillance:type=ALPR", - "surveillance:type=ANPR" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Surveillance Camera", - "nl": "Bewakingscamera", - "ru": "Камера наблюдения", - "fr": "Caméra de surveillance", - "it": "Videocamera di sorveglianza" - } - }, - "tagRenderings": [ - "images", - { - "#": "Camera type: fixed; panning; dome", - "question": { - "en": "What kind of camera is this?", - "nl": "Wat voor soort camera is dit?", - "fr": "Quel genre de caméra est-ce ?", - "it": "Di che tipo di videocamera si tratta?", - "ru": "Какая это камера?" - }, - "mappings": [ - { - "if": { - "and": [ - "camera:type=fixed" - ] - }, - "then": { - "en": "A fixed (non-moving) camera", - "nl": "Een vaste camera", - "fr": "Une caméra fixe (non mobile)", - "it": "Una videocamera fissa (non semovente)" - } - }, - { - "if": { - "and": [ - "camera:type=dome" - ] - }, - "then": { - "en": "A dome camera (which can turn)", - "nl": "Een dome (bolvormige camera die kan draaien)", - "fr": "Une caméra dôme (qui peut tourner)", - "it": "Una videocamera a cupola (che può ruotare)", - "ru": "Камера с поворотным механизмом" - } - }, - { - "if": { - "and": [ - "camera:type=panning" - ] - }, - "then": { - "en": "A panning camera", - "nl": "Een camera die (met een motor) van links naar rechts kan draaien", - "ru": "Панорамная камера", - "fr": "Une caméra panoramique", - "it": "Una videocamera panoramica" - } - } - ] + "id": "surveillance_camera", + "name": { + "en": "Surveillance camera's", + "nl": "Bewakingscamera's", + "ru": "Камеры наблюдения", + "fr": "Caméras de surveillance", + "it": "Videocamere di sorveglianza" }, - { - "#": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view", - "question": { - "en": "In which geographical direction does this camera film?", - "nl": "In welke geografische richting filmt deze camera?", - "fr": "Dans quelle direction géographique cette caméra filme-t-elle ?", - "it": "In quale direzione geografica punta questa videocamera?" - }, - "render": { - "en": "Films to a compass heading of {camera:direction}", - "nl": "Filmt in kompasrichting {camera:direction}", - "fr": "Filme dans une direction {camera:direction}", - "it": "Punta in direzione {camera:direction}" - }, - "condition": { - "or": [ - "camera:direction~*", - "direction~*", - "camera:type!=dome", - { + "minzoom": 12, + "source": { + "osmTags": { "and": [ - "camera:type=dome", - "camera:mount=wall" + "man_made=surveillance", + { + "or": [ + "surveillance:type=camera", + "surveillance:type=ALPR", + "surveillance:type=ANPR" + ] + } ] - } - ] - }, - "freeform": { - "key": "camera:direction", - "type": "direction" - }, - "mappings": [ - { - "if": { - "and": [ - "camera:direction=", - "direction~*" - ] - }, - "then": { - "en": "Films to a compass heading of {direction}", - "nl": "Filmt in kompasrichting {direction}", - "fr": "Filme dans une direction {direction}", - "it": "Punta in direzione {direction}" - }, - "hideInAnswer": true } - ] }, - { - "#": "Operator", - "freeform": { - "key": "operator" - }, - "question": { - "en": "Who operates this CCTV?", - "nl": "Wie beheert deze bewakingscamera?", - "fr": "Qui exploite ce système de vidéosurveillance ?", - "it": "Chi gestisce questa videocamera a circuito chiuso?" - }, - "render": { - "en": "Operated by {operator}", - "nl": "Beheer door {operator}", - "fr": "Exploité par {operator}", - "it": "È gestita da {operator}" - } - }, - { - "#": "Surveillance type: public, outdoor, indoor", - "question": { - "en": "What kind of surveillance is this camera", - "nl": "Wat soort bewaking wordt hier uitgevoerd?", - "fr": "Quel genre de surveillance est cette caméra", - "it": "Che cosa sorveglia questa videocamera" - }, - "mappings": [ - { - "if": { - "and": [ - "surveillance=public" - ] - }, - "then": { - "en": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,...", - "nl": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel...", - "fr": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…", - "it": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." - } - }, - { - "if": { - "and": [ - "surveillance=outdoor" - ] - }, - "then": { - "en": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)", - "nl": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)", - "fr": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)", - "it": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" - } - }, - { - "if": { - "and": [ - "surveillance=indoor" - ] - }, - "then": { - "nl": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ...", - "en": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ...", - "fr": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…", - "it": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." - } + "title": { + "render": { + "en": "Surveillance Camera", + "nl": "Bewakingscamera", + "ru": "Камера наблюдения", + "fr": "Caméra de surveillance", + "it": "Videocamera di sorveglianza" } - ] }, - { - "#": "Indoor camera? This isn't clear for 'public'-cameras", - "question": { - "en": "Is the public space surveilled by this camera an indoor or outdoor space?", - "nl": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?", - "fr": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?", - "it": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" - }, - "condition": { - "and": [ - "surveillance:type=public" - ] - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "indoor=yes", - "then": { - "en": "This camera is located indoors", - "nl": "Deze camera bevindt zich binnen", - "fr": "Cette caméra est située à l'intérieur", - "it": "Questa videocamera si trova al chiuso" - } + "question": { + "en": "What kind of camera is this?", + "nl": "Wat voor soort camera is dit?", + "fr": "Quel genre de caméra est-ce ?", + "it": "Di che tipo di videocamera si tratta?", + "ru": "Какая это камера?" + }, + "mappings": [ + { + "if": { + "and": [ + "camera:type=fixed" + ] + }, + "then": { + "en": "A fixed (non-moving) camera", + "nl": "Een vaste camera", + "fr": "Une caméra fixe (non mobile)", + "it": "Una videocamera fissa (non semovente)" + } + }, + { + "if": { + "and": [ + "camera:type=dome" + ] + }, + "then": { + "en": "A dome camera (which can turn)", + "nl": "Een dome (bolvormige camera die kan draaien)", + "fr": "Une caméra dôme (qui peut tourner)", + "it": "Una videocamera a cupola (che può ruotare)", + "ru": "Камера с поворотным механизмом" + } + }, + { + "if": { + "and": [ + "camera:type=panning" + ] + }, + "then": { + "en": "A panning camera", + "nl": "Een camera die (met een motor) van links naar rechts kan draaien", + "ru": "Панорамная камера", + "fr": "Une caméra panoramique", + "it": "Una videocamera panoramica" + } + } + ], + "id": "Camera type: fixed; panning; dome" }, { - "if": "indoor=no", - "then": { - "en": "This camera is located outdoors", - "nl": "Deze camera bevindt zich buiten", - "fr": "Cette caméra est située à l'extérieur", - "it": "Questa videocamera si trova all'aperto", - "ru": "Эта камера расположена снаружи" - } + "question": { + "en": "In which geographical direction does this camera film?", + "nl": "In welke geografische richting filmt deze camera?", + "fr": "Dans quelle direction géographique cette caméra filme-t-elle ?", + "it": "In quale direzione geografica punta questa videocamera?" + }, + "render": { + "en": "Films to a compass heading of {camera:direction}", + "nl": "Filmt in kompasrichting {camera:direction}", + "fr": "Filme dans une direction {camera:direction}", + "it": "Punta in direzione {camera:direction}" + }, + "condition": { + "or": [ + "camera:direction~*", + "direction~*", + "camera:type!=dome", + { + "and": [ + "camera:type=dome", + "camera:mount=wall" + ] + } + ] + }, + "freeform": { + "key": "camera:direction", + "type": "direction" + }, + "mappings": [ + { + "if": { + "and": [ + "camera:direction=", + "direction~*" + ] + }, + "then": { + "en": "Films to a compass heading of {direction}", + "nl": "Filmt in kompasrichting {direction}", + "fr": "Filme dans une direction {direction}", + "it": "Punta in direzione {direction}" + }, + "hideInAnswer": true + } + ], + "id": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view" }, { - "if": "indoor=", - "then": { - "en": "This camera is probably located outdoors", - "nl": "Deze camera bevindt zich waarschijnlijk buiten", - "fr": "Cette caméra est probablement située à l'extérieur", - "it": "Questa videocamera si trova probabilmente all'esterno", - "ru": "Возможно, эта камера расположена снаружи" - }, - "hideInAnswer": true + "freeform": { + "key": "operator" + }, + "question": { + "en": "Who operates this CCTV?", + "nl": "Wie beheert deze bewakingscamera?", + "fr": "Qui exploite ce système de vidéosurveillance ?", + "it": "Chi gestisce questa videocamera a circuito chiuso?" + }, + "render": { + "en": "Operated by {operator}", + "nl": "Beheer door {operator}", + "fr": "Exploité par {operator}", + "it": "È gestita da {operator}" + }, + "id": "Operator" + }, + { + "question": { + "en": "What kind of surveillance is this camera", + "nl": "Wat soort bewaking wordt hier uitgevoerd?", + "fr": "Quel genre de surveillance est cette caméra", + "it": "Che cosa sorveglia questa videocamera" + }, + "mappings": [ + { + "if": { + "and": [ + "surveillance=public" + ] + }, + "then": { + "en": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,...", + "nl": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel...", + "fr": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…", + "it": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." + } + }, + { + "if": { + "and": [ + "surveillance=outdoor" + ] + }, + "then": { + "en": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)", + "nl": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)", + "fr": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)", + "it": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" + } + }, + { + "if": { + "and": [ + "surveillance=indoor" + ] + }, + "then": { + "nl": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ...", + "en": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ...", + "fr": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…", + "it": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." + } + } + ], + "id": "Surveillance type: public, outdoor, indoor" + }, + { + "question": { + "en": "Is the public space surveilled by this camera an indoor or outdoor space?", + "nl": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?", + "fr": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?", + "it": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" + }, + "condition": { + "and": [ + "surveillance:type=public" + ] + }, + "mappings": [ + { + "if": "indoor=yes", + "then": { + "en": "This camera is located indoors", + "nl": "Deze camera bevindt zich binnen", + "fr": "Cette caméra est située à l'intérieur", + "it": "Questa videocamera si trova al chiuso" + } + }, + { + "if": "indoor=no", + "then": { + "en": "This camera is located outdoors", + "nl": "Deze camera bevindt zich buiten", + "fr": "Cette caméra est située à l'extérieur", + "it": "Questa videocamera si trova all'aperto", + "ru": "Эта камера расположена снаружи" + } + }, + { + "if": "indoor=", + "then": { + "en": "This camera is probably located outdoors", + "nl": "Deze camera bevindt zich waarschijnlijk buiten", + "fr": "Cette caméra est probablement située à l'extérieur", + "it": "Questa videocamera si trova probabilmente all'esterno", + "ru": "Возможно, эта камера расположена снаружи" + }, + "hideInAnswer": true + } + ], + "id": "Indoor camera? This isn't clear for 'public'-cameras" + }, + { + "question": { + "en": "On which level is this camera located?", + "nl": "Op welke verdieping bevindt deze camera zich?", + "fr": "À quel niveau se trouve cette caméra ?", + "it": "A che piano si trova questa videocamera?" + }, + "render": { + "en": "Located on level {level}", + "nl": "Bevindt zich op verdieping {level}", + "fr": "Situé au niveau {level}", + "it": "Si trova al piano {level}" + }, + "freeform": { + "key": "level", + "type": "nat" + }, + "condition": { + "or": [ + "indoor=yes", + "surveillance:type=ye" + ] + }, + "id": "Level" + }, + { + "question": { + "en": "What exactly is surveilled here?", + "nl": "Wat wordt hier precies bewaakt?", + "fr": "Qu'est-ce qui est surveillé ici ?", + "it": "Che cosa è sorvegliato qui?" + }, + "freeform": { + "key": "surveillance:zone" + }, + "render": { + "en": " Surveills a {surveillance:zone}", + "nl": "Bewaakt een {surveillance:zone}", + "fr": " Surveille un(e) {surveillance:zone}", + "it": " Sorveglia una {surveillance:zone}" + }, + "mappings": [ + { + "if": { + "and": [ + "surveillance:zone=parking" + ] + }, + "then": { + "en": "Surveills a parking", + "nl": "Bewaakt een parking", + "fr": "Surveille un parking", + "it": "Sorveglia un parcheggio" + } + }, + { + "if": { + "and": [ + "surveillance:zone=traffic" + ] + }, + "then": { + "en": "Surveills the traffic", + "nl": "Bewaakt het verkeer", + "fr": "Surveille la circulation", + "it": "Sorveglia il traffico" + } + }, + { + "if": { + "and": [ + "surveillance:zone=entrance" + ] + }, + "then": { + "en": "Surveills an entrance", + "nl": "Bewaakt een ingang", + "fr": "Surveille une entrée", + "it": "Sorveglia un ingresso" + } + }, + { + "if": { + "and": [ + "surveillance:zone=corridor" + ] + }, + "then": { + "en": "Surveills a corridor", + "nl": "Bewaakt een gang", + "fr": "Surveille un couloir", + "it": "Sorveglia un corridoio" + } + }, + { + "if": { + "and": [ + "surveillance:zone=public_transport_platform" + ] + }, + "then": { + "en": "Surveills a public tranport platform", + "nl": "Bewaakt een perron of bushalte", + "fr": "Surveille un quai de transport public", + "it": "Sorveglia una pensilina del trasporto pubblico" + } + }, + { + "if": { + "and": [ + "surveillance:zone=shop" + ] + }, + "then": { + "en": "Surveills a shop", + "nl": "Bewaakt een winkel", + "fr": "Surveille un magasin", + "it": "Sorveglia un negozio" + } + } + ], + "id": "Surveillance:zone" + }, + { + "question": { + "en": "How is this camera placed?", + "nl": "Hoe is deze camera geplaatst?", + "fr": "Comment cette caméra est-elle placée ?", + "it": "Com'è posizionata questa telecamera?", + "ru": "Как расположена эта камера?" + }, + "render": { + "en": "Mounting method: {mount}", + "nl": "Montage: {camera:mount}", + "fr": "Méthode de montage : {mount}", + "it": "Metodo di montaggio: {mount}" + }, + "freeform": { + "key": "camera:mount" + }, + "mappings": [ + { + "if": "camera:mount=wall", + "then": { + "en": "This camera is placed against a wall", + "nl": "Deze camera hangt aan een muur", + "fr": "Cette caméra est placée contre un mur", + "it": "Questa telecamera è posizionata contro un muro" + } + }, + { + "if": "camera:mount=pole", + "then": { + "en": "This camera is placed one a pole", + "nl": "Deze camera staat op een paal", + "fr": "Cette caméra est placée sur un poteau", + "it": "Questa telecamera è posizionata su un palo" + } + }, + { + "if": "camera:mount=ceiling", + "then": { + "en": "This camera is placed on the ceiling", + "nl": "Deze camera hangt aan het plafond", + "fr": "Cette caméra est placée au plafond", + "it": "Questa telecamera è posizionata sul soffitto" + } + } + ], + "id": "camera:mount" } - ] - }, - { - "#": "Level", - "question": { - "en": "On which level is this camera located?", - "nl": "Op welke verdieping bevindt deze camera zich?", - "fr": "À quel niveau se trouve cette caméra ?", - "it": "A che piano si trova questa videocamera?" - }, - "render": { - "en": "Located on level {level}", - "nl": "Bevindt zich op verdieping {level}", - "fr": "Situé au niveau {level}", - "it": "Si trova al piano {level}" - }, - "freeform": { - "key": "level", - "type": "nat" - }, - "condition": { - "or": [ - "indoor=yes", - "surveillance:type=ye" - ] - } - }, - { - "#": "Surveillance:zone", - "question": { - "en": "What exactly is surveilled here?", - "nl": "Wat wordt hier precies bewaakt?", - "fr": "Qu'est-ce qui est surveillé ici ?", - "it": "Che cosa è sorvegliato qui?" - }, - "freeform": { - "key": "surveillance:zone" - }, - "render": { - "en": " Surveills a {surveillance:zone}", - "nl": "Bewaakt een {surveillance:zone}", - "fr": " Surveille un(e) {surveillance:zone}", - "it": " Sorveglia una {surveillance:zone}" - }, - "mappings": [ - { - "if": { - "and": [ - "surveillance:zone=parking" - ] - }, - "then": { - "en": "Surveills a parking", - "nl": "Bewaakt een parking", - "fr": "Surveille un parking", - "it": "Sorveglia un parcheggio" - } - }, - { - "if": { - "and": [ - "surveillance:zone=traffic" - ] - }, - "then": { - "en": "Surveills the traffic", - "nl": "Bewaakt het verkeer", - "fr": "Surveille la circulation", - "it": "Sorveglia il traffico" - } - }, - { - "if": { - "and": [ - "surveillance:zone=entrance" - ] - }, - "then": { - "en": "Surveills an entrance", - "nl": "Bewaakt een ingang", - "fr": "Surveille une entrée", - "it": "Sorveglia un ingresso" - } - }, - { - "if": { - "and": [ - "surveillance:zone=corridor" - ] - }, - "then": { - "en": "Surveills a corridor", - "nl": "Bewaakt een gang", - "fr": "Surveille un couloir", - "it": "Sorveglia un corridoio" - } - }, - { - "if": { - "and": [ - "surveillance:zone=public_transport_platform" - ] - }, - "then": { - "en": "Surveills a public tranport platform", - "nl": "Bewaakt een perron of bushalte", - "fr": "Surveille un quai de transport public", - "it": "Sorveglia una pensilina del trasporto pubblico" - } - }, - { - "if": { - "and": [ - "surveillance:zone=shop" - ] - }, - "then": { - "en": "Surveills a shop", - "nl": "Bewaakt een winkel", - "fr": "Surveille un magasin", - "it": "Sorveglia un negozio" - } - } - ] - }, - { - "#": "camera:mount", - "question": { - "en": "How is this camera placed?", - "nl": "Hoe is deze camera geplaatst?", - "fr": "Comment cette caméra est-elle placée ?", - "it": "Com'è posizionata questa telecamera?", - "ru": "Как расположена эта камера?" - }, - "render": { - "en": "Mounting method: {mount}", - "nl": "Montage: {camera:mount}", - "fr": "Méthode de montage : {mount}", - "it": "Metodo di montaggio: {mount}" - }, - "freeform": { - "key": "camera:mount" - }, - "mappings": [ - { - "if": "camera:mount=wall", - "then": { - "en": "This camera is placed against a wall", - "nl": "Deze camera hangt aan een muur", - "fr": "Cette caméra est placée contre un mur", - "it": "Questa telecamera è posizionata contro un muro" - } - }, - { - "if": "camera:mount=pole", - "then": { - "en": "This camera is placed one a pole", - "nl": "Deze camera staat op een paal", - "fr": "Cette caméra est placée sur un poteau", - "it": "Questa telecamera è posizionata su un palo" - } - }, - { - "if": "camera:mount=ceiling", - "then": { - "en": "This camera is placed on the ceiling", - "nl": "Deze camera hangt aan het plafond", - "fr": "Cette caméra est placée au plafond", - "it": "Questa telecamera è posizionata sul soffitto" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/surveillance/logo.svg", - "mappings": [ - { - "if": "camera:type=dome", - "then": "./assets/themes/surveillance/dome.svg" - }, - { - "if": "_direction:leftright=right", - "then": "./assets/themes/surveillance/cam_right.svg" - }, - { - "if": "_direction:leftright=left", - "then": "./assets/themes/surveillance/cam_left.svg" - } - ] - }, - "rotation": { - "#": "Note: {camera:direction} is substituted by a number, giving the string 'calc(123deg + 90deg)' ; it is this string that is used as css property, which interprets the calc", - "render": "calc({_direction:numerical}deg + 90deg)", - "mappings": [ - { - "if": "camera:type=dome", - "then": "0" - }, - { - "if": "_direction:leftright=right", - "then": "calc({_direction:numerical}deg - 90deg)" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "mappings": [ - { - "if": "camera:type=dome", - "then": "50,50,center" - }, - { - "if": "_direction:leftright~*", - "then": "100,35,center" - } ], - "render": "50,50,center" - }, - "color": { - "render": "#f00" - }, - "presets": [ - { - "tags": [ - "man_made=surveillance", - "surveillance:type=camera" - ], - "title": "Surveillance camera" - } - ], - "wayHandling": 2 + "icon": { + "render": "./assets/themes/surveillance/logo.svg", + "mappings": [ + { + "if": "camera:type=dome", + "then": "./assets/themes/surveillance/dome.svg" + }, + { + "if": "_direction:leftright=right", + "then": "./assets/themes/surveillance/cam_right.svg" + }, + { + "if": "_direction:leftright=left", + "then": "./assets/themes/surveillance/cam_left.svg" + } + ] + }, + "rotation": { + "#": "Note: {camera:direction} is substituted by a number, giving the string 'calc(123deg + 90deg)' ; it is this string that is used as css property, which interprets the calc", + "render": "calc({_direction:numerical}deg + 90deg)", + "mappings": [ + { + "if": "camera:type=dome", + "then": "0" + }, + { + "if": "_direction:leftright=right", + "then": "calc({_direction:numerical}deg - 90deg)" + } + ] + }, + "width": { + "render": "8" + }, + "iconSize": { + "mappings": [ + { + "if": "camera:type=dome", + "then": "50,50,center" + }, + { + "if": "_direction:leftright~*", + "then": "100,35,center" + } + ], + "render": "50,50,center" + }, + "color": { + "render": "#f00" + }, + "presets": [ + { + "tags": [ + "man_made=surveillance", + "surveillance:type=camera" + ], + "title": "Surveillance camera" + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index fd1043c8a..8b10b35ee 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -1,443 +1,499 @@ { - "id": "toilet", - "name": { - "en": "Toilets", - "de": "Toiletten", - "fr": "Toilettes", - "nl": "Toiletten", - "ru": "Туалеты", - "it": "Servizi igienici" - }, - "minzoom": 12, - "source": { - "osmTags": "amenity=toilets" - }, - "title": { - "render": { - "en": "Toilet", - "de": "Toilette", - "fr": "Toilettes", - "nl": "Toilet", - "ru": "Туалет", - "it": "Servizi igienici" - } - }, - "icon": { - "render": "./assets/layers/toilet/toilets.svg", - "mappings": [ - { - "if": "wheelchair=yes", - "then": "./assets/layers/toilet/wheelchair.svg" - }, - { - "if": { - "or": [ - "toilets:position=urinals", - "toilets:position=urinal" - ] - }, - "then": "./assets/layers/toilet/urinal.svg" - } - ] - }, - "color": { - "render": "#0000ff" - }, - "wayHandling": 1, - "presets": [ - { - "title": { - "en": "Toilet", - "de": "Toilette", + "id": "toilet", + "name": { + "en": "Toilets", + "de": "Toiletten", "fr": "Toilettes", - "nl": "Toilet", - "ru": "Туалет", + "nl": "Toiletten", + "ru": "Туалеты", "it": "Servizi igienici" - }, - "tags": [ - "amenity=toilets" - ], - "description": { - "en": "A publicly accessible toilet or restroom", - "de": "Eine öffentlich zugängliche Toilette", - "fr": "Des toilettes", - "nl": "Een publieke toilet", - "it": "Servizi igienici aperti al pubblico", - "ru": "Туалет или комната отдыха со свободным доступом" - } }, - { - "title": { - "en": "Toilets with wheelchair accessible toilet", - "de": "Toiletten mit rollstuhlgerechter Toilette", - "fr": "Toilettes accessible aux personnes à mobilité réduite", - "nl": "Een rolstoeltoegankelijke toilet", - "it": "Servizi igienici accessibili per persone in sedia a rotelle", - "ru": "Туалет с доступом для пользователей кресел-колясок" - }, - "tags": [ - "amenity=toilets", - "wheelchair=yes" - ], - "description": { - "en": "A restroom which has at least one wheelchair-accessible toilet", - "de": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", - "fr": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", - "nl": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", - "it": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle" - } - } - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Are these toilets publicly accessible?", - "de": "Sind diese Toiletten öffentlich zugänglich?", - "fr": "Ces toilettes sont-elles accessibles au public ?", - "nl": "Zijn deze toiletten publiek toegankelijk?", - "it": "Questi servizi igienici sono aperti al pubblico?", - "ru": "Есть ли свободный доступ к этим туалетам?" - }, - "render": { - "en": "Access is {access}", - "de": "Zugang ist {access}", - "fr": "L'accès est {access}", - "nl": "Toegankelijkheid is {access}", - "it": "L'accesso è {access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=the tag access was filled out by the user and might need refinement" + "minzoom": 12, + "source": { + "osmTags": "amenity=toilets" + }, + "title": { + "render": { + "en": "Toilet", + "de": "Toilette", + "fr": "Toilettes", + "nl": "Toilet", + "ru": "Туалет", + "it": "Servizi igienici" + } + }, + "icon": { + "render": "./assets/layers/toilet/toilets.svg", + "mappings": [ + { + "if": "wheelchair=yes", + "then": "circle:white;./assets/layers/toilet/wheelchair.svg" + }, + { + "if": { + "or": [ + "toilets:position=urinals", + "toilets:position=urinal" + ] + }, + "then": "./assets/layers/toilet/urinal.svg" + } ] - }, - "mappings": [ - { - "if": "access=yes", - "then": { - "en": "Public access", - "de": "Öffentlicher Zugang", - "fr": "Accès publique", - "nl": "Publiek toegankelijk", - "it": "Accesso pubblico", - "ru": "Свободный доступ" - } - }, - { - "if": "access=customers", - "then": { - "en": "Only access to customers", - "de": "Nur Zugang für Kunden", - "fr": "Accès réservé aux clients", - "nl": "Enkel toegang voor klanten", - "it": "Accesso riservato ai clienti e alle clienti" - } - }, - { - "if": "access=no", - "then": { - "en": "Not accessible", - "de": "Nicht zugänglich", - "fr": "Toilettes privées", - "nl": "Niet toegankelijk", - "ru": "Недоступно", - "it": "Non accessibile" - } - }, - { - "if": "access=key", - "then": { - "en": "Accessible, but one has to ask a key to enter", - "de": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen", - "fr": "Accessible, mais vous devez demander la clé", - "nl": "Toegankelijk na het vragen van de sleutel", - "it": "Accessibile, ma occorre chiedere una chiave per accedere" - } - }, - { - "if": "access=public", - "then": { - "en": "Public access", - "de": "Öffentlicher Zugang", - "fr": "Accès publique", - "nl": "Publiek toegankelijk", - "it": "Accesso pubblico", - "ru": "Свободный доступ" - }, - "hideInAnswer": true - } - ] }, - { - "question": { - "en": "Are these toilets free to use?", - "de": "Können diese Toiletten kostenlos benutzt werden?", - "fr": "Ces toilettes sont-elles payantes ?", - "nl": "Zijn deze toiletten gratis te gebruiken?", - "it": "Questi servizi igienici sono gratuiti?" - }, - "mappings": [ - { - "then": { - "en": "These are paid toilets", - "de": "Dies sind bezahlte Toiletten", - "fr": "Toilettes payantes", - "nl": "Men moet betalen om deze toiletten te gebruiken", - "ru": "Это платные туалеты", - "it": "Questi servizi igienici sono a pagamento" - }, - "if": "fee=yes" - }, - { - "if": "fee=no", - "then": { - "en": "Free to use", - "de": "Kostenlose Nutzung", - "fr": "Toilettes gratuites", - "nl": "Gratis te gebruiken", - "it": "Gratis" - } - } - ] + "color": { + "render": "#0000ff" }, - { - "question": { - "en": "How much does one have to pay for these toilets?", - "de": "Wie viel muss man für diese Toiletten bezahlen?", - "fr": "Quel est le prix d'accès de ces toilettes ?", - "nl": "Hoeveel moet men betalen om deze toiletten te gebruiken?", - "it": "Quanto costa l'accesso a questi servizi igienici?", - "ru": "Сколько стоит посещение туалета?" - }, - "render": { - "en": "The fee is {charge}", - "de": "Die Gebühr beträgt {charge}", - "fr": "Le prix est {charge}", - "nl": "De toiletten gebruiken kost {charge}", - "it": "La tariffa è {charge}", - "ru": "Стоимость {charge}" - }, - "condition": "fee=yes", - "freeform": { - "key": "charge", - "type": "string" - } - }, - { - "question": { - "en": "Is there a dedicated toilet for wheelchair users", - "de": "Gibt es eine Toilette für Rollstuhlfahrer?", - "fr": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?", - "nl": "Is er een rolstoeltoegankelijke toilet voorzien?", - "it": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "mappings": [ + "wayHandling": 1, + "presets": [ { - "then": { - "en": "There is a dedicated toilet for wheelchair users", - "de": "Es gibt eine Toilette für Rollstuhlfahrer", - "fr": "Il y a des toilettes réservées pour les personnes à mobilité réduite", - "nl": "Er is een toilet voor rolstoelgebruikers", - "it": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "if": "wheelchair=yes" + "title": { + "en": "toilet", + "de": "toilette", + "fr": "toilettes", + "nl": "toilet", + "ru": "tуалет", + "it": "servizi igienici" + }, + "tags": [ + "amenity=toilets" + ], + "description": { + "en": "A publicly accessible toilet or restroom", + "de": "Eine öffentlich zugängliche Toilette", + "fr": "Des toilettes", + "nl": "Een publieke toilet", + "it": "Servizi igienici aperti al pubblico", + "ru": "Туалет или комната отдыха со свободным доступом" + } }, { - "if": "wheelchair=no", - "then": { - "en": "No wheelchair access", - "de": "Kein Zugang für Rollstuhlfahrer", - "fr": "Non accessible aux personnes à mobilité réduite", - "nl": "Niet toegankelijk voor rolstoelgebruikers", - "it": "Non accessibile in sedia a rotelle", - "ru": "Недоступно пользователям кресел-колясок" - } + "title": { + "en": "toilets with wheelchair accessible toilet", + "de": "toiletten mit rollstuhlgerechter Toilette", + "fr": "toilettes accessible aux personnes à mobilité réduite", + "nl": "een rolstoeltoegankelijke toilet", + "it": "servizi igienici accessibili per persone in sedia a rotelle", + "ru": "tуалет с доступом для пользователей кресел-колясок" + }, + "tags": [ + "amenity=toilets", + "wheelchair=yes" + ], + "description": { + "en": "A restroom which has at least one wheelchair-accessible toilet", + "de": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", + "fr": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", + "nl": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", + "it": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle" + } } - ] - }, - { - "question": { - "en": "Which kind of toilets are this?", - "de": "Welche Art von Toiletten sind das?", - "fr": "De quel type sont ces toilettes ?", - "nl": "Welke toiletten zijn dit?", - "it": "Di che tipo di servizi igienici si tratta?", - "ru": "Какие это туалеты?" - }, - "mappings": [ + ], + "tagRenderings": [ + "images", { - "if": "toilets:position=seated", - "then": { - "en": "There are only seated toilets", - "de": "Es gibt nur Sitztoiletten", - "fr": "Il y a uniquement des sièges de toilettes", - "nl": "Er zijn enkel WC's om op te zitten", - "it": "Ci sono solo WC con sedile" - } + "question": { + "en": "Are these toilets publicly accessible?", + "de": "Sind diese Toiletten öffentlich zugänglich?", + "fr": "Ces toilettes sont-elles accessibles au public ?", + "nl": "Zijn deze toiletten publiek toegankelijk?", + "it": "Questi servizi igienici sono aperti al pubblico?", + "ru": "Есть ли свободный доступ к этим туалетам?" + }, + "render": { + "en": "Access is {access}", + "de": "Zugang ist {access}", + "fr": "L'accès est {access}", + "nl": "Toegankelijkheid is {access}", + "it": "L'accesso è {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=the tag access was filled out by the user and might need refinement" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Public access", + "de": "Öffentlicher Zugang", + "fr": "Accès publique", + "nl": "Publiek toegankelijk", + "it": "Accesso pubblico", + "ru": "Свободный доступ" + } + }, + { + "if": "access=customers", + "then": { + "en": "Only access to customers", + "de": "Nur Zugang für Kunden", + "fr": "Accès réservé aux clients", + "nl": "Enkel toegang voor klanten", + "it": "Accesso riservato ai clienti e alle clienti" + } + }, + { + "if": "access=no", + "then": { + "en": "Not accessible", + "de": "Nicht zugänglich", + "fr": "Toilettes privées", + "nl": "Niet toegankelijk", + "ru": "Недоступно", + "it": "Non accessibile" + } + }, + { + "if": "access=key", + "then": { + "en": "Accessible, but one has to ask a key to enter", + "de": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen", + "fr": "Accessible, mais vous devez demander la clé", + "nl": "Toegankelijk na het vragen van de sleutel", + "it": "Accessibile, ma occorre chiedere una chiave per accedere" + } + }, + { + "if": "access=public", + "then": { + "en": "Public access", + "de": "Öffentlicher Zugang", + "fr": "Accès publique", + "nl": "Publiek toegankelijk", + "it": "Accesso pubblico", + "ru": "Свободный доступ" + }, + "hideInAnswer": true + } + ], + "id": "toilet-access" }, { - "if": "toilets:position=urinal", - "then": { - "en": "There are only urinals here", - "de": "Hier gibt es nur Pissoirs", - "fr": "Il y a uniquement des urinoirs", - "nl": "Er zijn enkel urinoirs", - "it": "Ci sono solo urinali" - } - }, - { - "if": "toilets:position=squat", - "then": { - "en": "There are only squat toilets here", - "de": "Es gibt hier nur Hocktoiletten", - "fr": "Il y a uniquement des toilettes turques", - "nl": "Er zijn enkel hurktoiletten", - "it": "Ci sono solo turche" - } - }, - { - "if": "toilets:position=seated;urinal", - "then": { - "en": "Both seated toilets and urinals are available here", - "de": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar", - "fr": "Il y a des sièges de toilettes et des urinoirs", - "nl": "Er zijn zowel urinoirs als zittoiletten", - "it": "Ci sono sia sedili, sia urinali" - } - } - ] - }, - { - "question": { - "en": "Is a changing table (to change diapers) available?", - "de": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?", - "fr": "Ces toilettes disposent-elles d'une table à langer ?", - "nl": "Is er een luiertafel beschikbaar?", - "it": "È disponibile un fasciatoio (per cambiare i pannolini)?" - }, - "mappings": [ - { - "then": { - "en": "A changing table is available", - "de": "Ein Wickeltisch ist verfügbar", - "fr": "Une table à langer est disponible", - "nl": "Er is een luiertafel", - "it": "È disponibile un fasciatoio" - }, - "if": "changing_table=yes" - }, - { - "if": "changing_table=no", - "then": { - "en": "No changing table is available", - "de": "Es ist kein Wickeltisch verfügbar", - "fr": "Aucune table à langer", - "nl": "Geen luiertafel", - "it": "Non è disponibile un fasciatoio" - } - } - ] - }, - { - "question": { - "en": "Where is the changing table located?", - "de": "Wo befindet sich der Wickeltisch?", - "fr": "Où se situe la table à langer ?", - "nl": "Waar bevindt de luiertafel zich?", - "it": "Dove si trova il fasciatoio?" - }, - "render": { - "en": "The changing table is located at {changing_table:location}", - "de": "Die Wickeltabelle befindet sich in {changing_table:location}", - "fr": "Emplacement de la table à langer : {changing_table:location}", - "nl": "De luiertafel bevindt zich in {changing_table:location}", - "it": "Il fasciatoio si trova presso {changing_table:location}" - }, - "condition": "changing_table=yes", - "freeform": { - "key": "changing_table:location" - }, - "mappings": [ - { - "then": { - "en": "The changing table is in the toilet for women. ", - "de": "Der Wickeltisch befindet sich in der Damentoilette. ", - "fr": "La table à langer est dans les toilettes pour femmes. ", - "nl": "De luiertafel bevindt zich in de vrouwentoiletten ", - "it": "Il fasciatoio è nei servizi igienici femminili. " - }, - "if": "changing_table:location=female_toilet" - }, - { - "then": { - "en": "The changing table is in the toilet for men. ", - "de": "Der Wickeltisch befindet sich in der Herrentoilette. ", - "fr": "La table à langer est dans les toilettes pour hommes. ", - "nl": "De luiertafel bevindt zich in de herentoiletten ", - "it": "Il fasciatoio è nei servizi igienici maschili. " - }, - "if": "changing_table:location=male_toilet" - }, - { - "if": "changing_table:location=wheelchair_toilet", - "then": { - "en": "The changing table is in the toilet for wheelchair users. ", - "de": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. ", - "fr": "La table à langer est dans les toilettes pour personnes à mobilité réduite. ", - "nl": "De luiertafel bevindt zich in de rolstoeltoegankelijke toilet ", - "it": "Il fasciatoio è nei servizi igienici per persone in sedia a rotelle. " - } - }, - { - "if": "changing_table:location=dedicated_room", - "then": { - "en": "The changing table is in a dedicated room. ", - "de": "Der Wickeltisch befindet sich in einem eigenen Raum. ", - "fr": "La table à langer est dans un espace dédié. ", - "nl": "De luiertafel bevindt zich in een daartoe voorziene kamer ", - "it": "Il fasciatoio è in una stanza dedicata. " - } - } - ] - } - ], - "filter": [ - { - "options": [ - { - "question": { - "en": "Wheelchair accessible" - }, - "osmTags": "wheelchair=yes" - } - ] - }, - { - "options": [ - { - "question": { - "en": "Has a changing table" - }, - "osmTags": "changing_table=yes" - } - ] - }, - { - "options": [ - { - "question": { - "en": "Free to use" - }, - "osmTags": { - "or": [ - "fee=no", - "fee=0", - "charge=0" + "id": "toilets-fee", + "question": { + "en": "Are these toilets free to use?", + "de": "Können diese Toiletten kostenlos benutzt werden?", + "fr": "Ces toilettes sont-elles payantes ?", + "nl": "Zijn deze toiletten gratis te gebruiken?", + "it": "Questi servizi igienici sono gratuiti?" + }, + "mappings": [ + { + "then": { + "en": "These are paid toilets", + "de": "Dies sind bezahlte Toiletten", + "fr": "Toilettes payantes", + "nl": "Men moet betalen om deze toiletten te gebruiken", + "ru": "Это платные туалеты", + "it": "Questi servizi igienici sono a pagamento" + }, + "if": "fee=yes" + }, + { + "if": "fee=no", + "then": { + "en": "Free to use", + "de": "Kostenlose Nutzung", + "fr": "Toilettes gratuites", + "nl": "Gratis te gebruiken", + "it": "Gratis" + } + } + ] + }, + { + "question": { + "en": "How much does one have to pay for these toilets?", + "de": "Wie viel muss man für diese Toiletten bezahlen?", + "fr": "Quel est le prix d'accès de ces toilettes ?", + "nl": "Hoeveel moet men betalen om deze toiletten te gebruiken?", + "it": "Quanto costa l'accesso a questi servizi igienici?", + "ru": "Сколько стоит посещение туалета?" + }, + "render": { + "en": "The fee is {charge}", + "de": "Die Gebühr beträgt {charge}", + "fr": "Le prix est {charge}", + "nl": "De toiletten gebruiken kost {charge}", + "it": "La tariffa è {charge}", + "ru": "Стоимость {charge}" + }, + "condition": "fee=yes", + "freeform": { + "key": "charge", + "type": "string" + }, + "id": "toilet-charge" + }, + { + "id": "toilets-wheelchair", + "question": { + "en": "Is there a dedicated toilet for wheelchair users", + "de": "Gibt es eine Toilette für Rollstuhlfahrer?", + "fr": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?", + "nl": "Is er een rolstoeltoegankelijke toilet voorzien?", + "it": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "mappings": [ + { + "then": { + "en": "There is a dedicated toilet for wheelchair users", + "de": "Es gibt eine Toilette für Rollstuhlfahrer", + "fr": "Il y a des toilettes réservées pour les personnes à mobilité réduite", + "nl": "Er is een toilet voor rolstoelgebruikers", + "it": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "if": "wheelchair=yes" + }, + { + "if": "wheelchair=no", + "then": { + "en": "No wheelchair access", + "de": "Kein Zugang für Rollstuhlfahrer", + "fr": "Non accessible aux personnes à mobilité réduite", + "nl": "Niet toegankelijk voor rolstoelgebruikers", + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступно пользователям кресел-колясок" + } + } + ] + }, + { + "id": "toilets-type", + "question": { + "en": "Which kind of toilets are this?", + "de": "Welche Art von Toiletten sind das?", + "fr": "De quel type sont ces toilettes ?", + "nl": "Welke toiletten zijn dit?", + "it": "Di che tipo di servizi igienici si tratta?", + "ru": "Какие это туалеты?" + }, + "mappings": [ + { + "if": "toilets:position=seated", + "then": { + "en": "There are only seated toilets", + "de": "Es gibt nur Sitztoiletten", + "fr": "Il y a uniquement des sièges de toilettes", + "nl": "Er zijn enkel WC's om op te zitten", + "it": "Ci sono solo WC con sedile" + } + }, + { + "if": "toilets:position=urinal", + "then": { + "en": "There are only urinals here", + "de": "Hier gibt es nur Pissoirs", + "fr": "Il y a uniquement des urinoirs", + "nl": "Er zijn enkel urinoirs", + "it": "Ci sono solo urinali" + } + }, + { + "if": "toilets:position=squat", + "then": { + "en": "There are only squat toilets here", + "de": "Es gibt hier nur Hocktoiletten", + "fr": "Il y a uniquement des toilettes turques", + "nl": "Er zijn enkel hurktoiletten", + "it": "Ci sono solo turche" + } + }, + { + "if": "toilets:position=seated;urinal", + "then": { + "en": "Both seated toilets and urinals are available here", + "de": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar", + "fr": "Il y a des sièges de toilettes et des urinoirs", + "nl": "Er zijn zowel urinoirs als zittoiletten", + "it": "Ci sono sia sedili, sia urinali" + } + } + ] + }, + { + "id": "toilets-changing-table", + "question": { + "en": "Is a changing table (to change diapers) available?", + "de": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?", + "fr": "Ces toilettes disposent-elles d'une table à langer ?", + "nl": "Is er een luiertafel beschikbaar?", + "it": "È disponibile un fasciatoio (per cambiare i pannolini)?" + }, + "mappings": [ + { + "then": { + "en": "A changing table is available", + "de": "Ein Wickeltisch ist verfügbar", + "fr": "Une table à langer est disponible", + "nl": "Er is een luiertafel", + "it": "È disponibile un fasciatoio" + }, + "if": "changing_table=yes" + }, + { + "if": "changing_table=no", + "then": { + "en": "No changing table is available", + "de": "Es ist kein Wickeltisch verfügbar", + "fr": "Aucune table à langer", + "nl": "Geen luiertafel", + "it": "Non è disponibile un fasciatoio" + } + } + ] + }, + { + "question": { + "en": "Where is the changing table located?", + "de": "Wo befindet sich der Wickeltisch?", + "fr": "Où se situe la table à langer ?", + "nl": "Waar bevindt de luiertafel zich?", + "it": "Dove si trova il fasciatoio?" + }, + "render": { + "en": "The changing table is located at {changing_table:location}", + "de": "Die Wickeltabelle befindet sich in {changing_table:location}", + "fr": "Emplacement de la table à langer : {changing_table:location}", + "nl": "De luiertafel bevindt zich in {changing_table:location}", + "it": "Il fasciatoio si trova presso {changing_table:location}" + }, + "condition": "changing_table=yes", + "freeform": { + "key": "changing_table:location" + }, + "mappings": [ + { + "then": { + "en": "The changing table is in the toilet for women. ", + "de": "Der Wickeltisch befindet sich in der Damentoilette. ", + "fr": "La table à langer est dans les toilettes pour femmes. ", + "nl": "De luiertafel bevindt zich in de vrouwentoiletten ", + "it": "Il fasciatoio è nei servizi igienici femminili. " + }, + "if": "changing_table:location=female_toilet" + }, + { + "then": { + "en": "The changing table is in the toilet for men. ", + "de": "Der Wickeltisch befindet sich in der Herrentoilette. ", + "fr": "La table à langer est dans les toilettes pour hommes. ", + "nl": "De luiertafel bevindt zich in de herentoiletten ", + "it": "Il fasciatoio è nei servizi igienici maschili. " + }, + "if": "changing_table:location=male_toilet" + }, + { + "if": "changing_table:location=wheelchair_toilet", + "then": { + "en": "The changing table is in the toilet for wheelchair users. ", + "de": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. ", + "fr": "La table à langer est dans les toilettes pour personnes à mobilité réduite. ", + "nl": "De luiertafel bevindt zich in de rolstoeltoegankelijke toilet ", + "it": "Il fasciatoio è nei servizi igienici per persone in sedia a rotelle. " + } + }, + { + "if": "changing_table:location=dedicated_room", + "then": { + "en": "The changing table is in a dedicated room. ", + "de": "Der Wickeltisch befindet sich in einem eigenen Raum. ", + "fr": "La table à langer est dans un espace dédié. ", + "nl": "De luiertafel bevindt zich in een daartoe voorziene kamer ", + "it": "Il fasciatoio è in una stanza dedicata. " + } + } + ], + "id": "toilet-changing_table:location" + }, + { + "id": "toilet-handwashing", + "question": { + "en": "Do these toilets have a sink to wash your hands?", + "nl": "Hebben deze toiletten een lavabo om de handen te wassen?" + }, + "mappings": [ + { + "if": "toilets:handwashing=yes", + "then": { + "en": "This toilets have a sink to wash your hands", + "nl": "Deze toiletten hebben een lavabo waar men de handen kan wassen" + } + }, + { + "if": "toilets:handwashing=no", + "then": { + "en": "This toilets don't have a sink to wash your hands", + "nl": "Deze toiletten hebben geen lavabo waar men de handen kan wassen" + } + } + ] + }, + { + "id": "toilet-has-paper", + "question": { + "en": "Does one have to bring their own toilet paper to this toilet?", + "nl": "Moet je je eigen toiletpappier meenemen naar deze toilet?" + }, + "mappings": [ + { + "if": "toilets:paper_supplied=yes", + "then": { + "en": "Toilet paper is equipped with toilet paper", + "nl": "Deze toilet is voorzien van toiletpapier" + } + }, + { + "if": "toilets:paper_supplied=no", + "then": { + "en": "You have to bring your own toilet paper to this toilet", + "nl": "Je moet je eigen toiletpapier meebrengen naar deze toilet" + } + } ] - } } - ] - } - ] + ], + "filter": [ + { + "id": "wheelchair", + "options": [ + { + "question": { + "en": "Wheelchair accessible" + }, + "osmTags": "wheelchair=yes" + } + ] + }, + { + "id": "changing_table", + "options": [ + { + "question": { + "en": "Has a changing table" + }, + "osmTags": "changing_table=yes" + } + ] + }, + { + "id": "free", + "options": [ + { + "question": { + "en": "Free to use" + }, + "osmTags": { + "or": [ + "fee=no", + "fee=0", + "charge=0" + ] + } + } + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/toilet/wheelchair.svg b/assets/layers/toilet/wheelchair.svg index 929ea6c40..d113492ad 100644 --- a/assets/layers/toilet/wheelchair.svg +++ b/assets/layers/toilet/wheelchair.svg @@ -2,76 +2,71 @@ image/svg+xml + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + id="defs9" /> + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="999" + id="namedview7" + showgrid="false" + inkscape:zoom="0.8559553" + inkscape:cx="-16.568588" + inkscape:cy="292.29436" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="layer2" /> - + inkscape:groupmode="layer" + id="layer2" + inkscape:label="background"> + + inkscape:groupmode="layer" + id="layer1" + inkscape:label="wheelchair"> \ No newline at end of file + inkscape:connector-curvature="0" + style="clip-rule:evenodd;fill:#000000;fill-rule:evenodd;stroke-width:0.66635805" + d="m 310.84431,395.24795 c -20.28873,40.10642 -62.75413,66.52908 -108.0502,66.52908 -66.52908,0 -120.790412,-54.26133 -120.790412,-120.79041 0,-46.71209 28.310452,-90.1207 70.555212,-109.36341 l 2.73376,35.67521 c -24.98647,15.74498 -40.3895,44.15435 -40.3895,73.93288 0,48.26215 39.36263,87.62413 87.62413,87.62413 44.15407,0 81.80523,-33.88535 86.93958,-77.35545 z" + id="path4" /> \ No newline at end of file diff --git a/assets/layers/trail/trail.json b/assets/layers/trail/trail.json index 4638de35e..5cd3e7037 100644 --- a/assets/layers/trail/trail.json +++ b/assets/layers/trail/trail.json @@ -1,207 +1,208 @@ { - "id": "trail", - "name": { - "en": "Trails", - "nl": "Wandeltochten" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "route=hiking", - "route=bycicle", - "route=horse" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Trail", - "nl": "Wandeltocht" + "id": "trail", + "name": { + "en": "Trails", + "nl": "Wandeltochten" }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "The trail is {_length:km} kilometers long", - "nl": "Deze wandeling is {_length:km} kilometer lang" - } - }, - { - "#": "Name", - "question": { - "nl": "Wat is de naam van deze wandeling?" - }, - "render": { - "nl": "Deze wandeling heet {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert deze wandeltocht?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { + "minzoom": 12, + "source": { + "osmTags": { "and": [ - "operator=Natuurpunt" + { + "or": [ + "route=hiking", + "route=bycicle", + "route=horse" + ] + } ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true } - ] }, - { - "#": "Color", - "question": { - "nl": "Welke kleur heeft deze wandeling?" - }, - "render": { - "nl": "Deze wandeling heeft kleur {colour}" - }, - "freeform": { - "key": "colour", - "type": "color" - }, - "mappings": [ - { - "if": "colour=blue", - "then": { - "nl": "Blauwe wandeling", - "en": "Blue trail" - } + "title": { + "render": { + "en": "Trail", + "nl": "Wandeltocht" }, - { - "if": "colour=red", - "then": { - "nl": "Rode wandeling", - "en": "Red trail" - } - }, - { - "if": "colour=green", - "then": { - "nl": "Groene wandeling", - "en": "Green trail" - } - }, - { - "if": "colour=yellow", - "then": { - "nl": "Gele wandeling", - "en": "Yellow trail" - } - } - ] + "mappings": [ + { + "if": "name~*", + "then": "{name}" + } + ] }, - { - "#": "Wheelchair access", - "question": { - "nl": "Is deze wandeling toegankelijk met de rolstoel?" - }, - "mappings": [ + "tagRenderings": [ + "images", { - "then": { - "nl": "deze wandeltocht is toegankelijk met de rolstoel" - }, - "if": "wheelchair=yes" + "id": "trail-length", + "render": { + "en": "The trail is {_length:km} kilometers long", + "nl": "Deze wandeling is {_length:km} kilometer lang" + } }, { - "then": { - "nl": "deze wandeltocht is niet toegankelijk met de rolstoel" - }, - "if": "wheelchair=no" + "question": { + "nl": "Wat is de naam van deze wandeling?" + }, + "render": { + "nl": "Deze wandeling heet {name}" + }, + "freeform": { + "key": "name" + }, + "id": "Name" + }, + { + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert deze wandeltocht?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + } + ], + "id": "Operator tag" + }, + { + "question": { + "nl": "Welke kleur heeft deze wandeling?" + }, + "render": { + "nl": "Deze wandeling heeft kleur {colour}" + }, + "freeform": { + "key": "colour", + "type": "color" + }, + "mappings": [ + { + "if": "colour=blue", + "then": { + "nl": "Blauwe wandeling", + "en": "Blue trail" + } + }, + { + "if": "colour=red", + "then": { + "nl": "Rode wandeling", + "en": "Red trail" + } + }, + { + "if": "colour=green", + "then": { + "nl": "Groene wandeling", + "en": "Green trail" + } + }, + { + "if": "colour=yellow", + "then": { + "nl": "Gele wandeling", + "en": "Yellow trail" + } + } + ], + "id": "Color" + }, + { + "question": { + "nl": "Is deze wandeling toegankelijk met de rolstoel?" + }, + "mappings": [ + { + "then": { + "nl": "deze wandeltocht is toegankelijk met de rolstoel" + }, + "if": "wheelchair=yes" + }, + { + "then": { + "nl": "deze wandeltocht is niet toegankelijk met de rolstoel" + }, + "if": "wheelchair=no" + } + ], + "id": "Wheelchair access" + }, + { + "question": { + "nl": "Is deze wandeltocht toegankelijk met de buggy?" + }, + "mappings": [ + { + "then": { + "nl": "deze wandeltocht is toegankelijk met de buggy" + }, + "if": "pushchair=yes" + }, + { + "then": { + "nl": "deze wandeltocht is niet toegankelijk met de buggy" + }, + "if": "pushchair=no" + } + ], + "id": "pushchair access" } - ] + ], + "icon": { + "render": "./assets/layers/trail/trail.svg", + "mappings": [ + { + "if": "wheelchair=yes", + "then": "./assets/layers/trail/wheelchair.svg" + }, + { + "if": "pushchair=yes", + "then": "./assets/layers/trail/pushchair.svg" + } + ] }, - { - "#": "pushchair access", - "question": { - "nl": "Is deze wandeltocht toegankelijk met de buggy?" - }, - "mappings": [ - { - "then": { - "nl": "deze wandeltocht is toegankelijk met de buggy" - }, - "if": "pushchair=yes" - }, - { - "then": { - "nl": "deze wandeltocht is niet toegankelijk met de buggy" - }, - "if": "pushchair=no" - } - ] + "description": { + "nl": "Aangeduide wandeltochten" + }, + "wayHandling": 0, + "width": { + "render": "3" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#335D9F", + "mappings": [ + { + "if": "colour~*", + "then": "{colour}" + } + ] + }, + "dashArray": { + "render": "5 5" } - ], - "icon": { - "render": "./assets/layers/trail/trail.svg", - "mappings": [ - { - "if": "wheelchair=yes", - "then": "./assets/layers/trail/wheelchair.svg" - }, - { - "if": "pushchair=yes", - "then": "./assets/layers/trail/pushchair.svg" - } - ] - }, - "description": { - "nl": "Aangeduide wandeltochten" - }, - "wayHandling": 0, - "width": { - "render": "3" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#335D9F", - "mappings": [ - { - "if": "colour~*", - "then": "{colour}" - } - ] - }, - "dashArray": { - "render": "5 5" - } } \ No newline at end of file diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index 31e348441..59c1d03c1 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -1,559 +1,567 @@ { - "id": "tree_node", - "name": { - "nl": "Boom", - "en": "Tree", - "it": "Albero", - "ru": "Дерево", - "fr": "Arbre" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "natural=tree" - ] - } - }, - "title": { - "render": { - "nl": "Boom", - "en": "Tree", - "it": "Albero", - "ru": "Дерево", - "fr": "Arbre" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}", - "en": "{name}", - "ca": "{name}", - "de": "{name}", - "fr": "{name}", - "it": "{name}", - "ru": "{name}", - "id": "{name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "Hoogte: {height}", - "en": "Height: {height}", - "it": "Altezza: {height}", - "ru": "Высота: {height}", - "fr": "Hauteur : {height}" - }, - "condition": { - "and": [ - "height~*" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "height~^[0-9.]+$" - ] - }, - "then": { - "nl": "Hoogte: {height} m", - "en": "Height: {height} m", - "it": "Altezza: {height} m", - "ru": "Высота: {height} м", - "fr": "Hauteur : {height} m" - } - } - ] - }, - { - "question": { - "nl": "Is dit een naald- of loofboom?", - "en": "Is this a broadleaved or needleleaved tree?", - "it": "Si tratta di un albero latifoglia o aghifoglia?", - "fr": "Cet arbre est-il un feuillu ou un résineux ?" - }, - "mappings": [ - { - "if": { - "and": [ - "leaf_type=broadleaved" - ] - }, - "then": { - "nl": "\"\"/ Loofboom", - "en": "\"\"/ Broadleaved", - "it": "\"\"/ Latifoglia", - "fr": "\"\"/ Feuillu" - } - }, - { - "if": { - "and": [ - "leaf_type=needleleaved" - ] - }, - "then": { - "nl": "\"\"/ Naaldboom", - "en": "\"\"/ Needleleaved", - "it": "\"\"/ Aghifoglia", - "fr": "\"\"/ Résineux" - } - }, - { - "if": { - "and": [ - "leaf_type=leafless" - ] - }, - "then": { - "nl": "\"\"/ Permanent bladloos", - "en": "\"\"/ Permanently leafless", - "it": "\"\"/ Privo di foglie (permanente)", - "fr": "\"\"/ Sans feuilles (Permanent)" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is.", - "en": "How significant is this tree? Choose the first answer that applies.", - "it": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde.", - "fr": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." - }, - "mappings": [ - { - "if": { - "and": [ - "denotation=landmark" - ] - }, - "then": { - "nl": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie.", - "en": "The tree is remarkable due to its size or prominent location. It is useful for navigation.", - "it": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione.", - "fr": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." - } - }, - { - "if": { - "and": [ - "denotation=natural_monument" - ] - }, - "then": { - "nl": "De boom is een natuurlijk monument, bijvoorbeeld doordat hij bijzonder oud of van een waardevolle soort is.", - "en": "The tree is a natural monument, e.g. because it is especially old, or of a valuable species.", - "it": "L’albero è un monumento naturale, ad esempio perché specialmente antico o appartenente a specie importanti.", - "fr": "Cet arbre est un monument naturel (ex : âge, espèce, etc…)" - } - }, - { - "if": { - "and": [ - "denotation=agricultural" - ] - }, - "then": { - "nl": "De boom wordt voor landbouwdoeleinden gebruikt, bijvoorbeeld in een boomgaard.", - "en": "The tree is used for agricultural purposes, e.g. in an orchard.", - "it": "L’albero è usato per scopi agricoli, ad esempio in un frutteto.", - "fr": "Cet arbre est utilisé à but d’agriculture (ex : dans un verger)" - } - }, - { - "if": { - "and": [ - "denotation=park" - ] - }, - "then": { - "nl": "De boom staat in een park of dergelijke (begraafplaats, schoolterrein, …).", - "en": "The tree is in a park or similar (cemetery, school grounds, …).", - "it": "L’albero è in un parco o qualcosa di simile (cimitero, aree didattiche, etc.).", - "fr": "Cet arbre est dans un parc ou une aire similaire (ex : cimetière, cour d’école, …)." - } - }, - { - "if": { - "and": [ - "denotation=garden" - ] - }, - "then": { - "nl": "De boom staat in de tuin bij een woning/flatgebouw.", - "en": "The tree is a residential garden.", - "it": "L’albero è un giardino residenziale.", - "fr": "Cet arbre est dans une cour résidentielle." - } - }, - { - "if": { - "and": [ - "denotation=avenue" - ] - }, - "then": { - "nl": "Dit is een laanboom.", - "en": "This is a tree along an avenue.", - "it": "Fa parte di un viale alberato.", - "fr": "C'est un arbre le long d'une avenue." - } - }, - { - "if": { - "and": [ - "denotation=urban" - ] - }, - "then": { - "nl": "De boom staat in een woonkern.", - "en": "The tree is an urban area.", - "it": "L’albero si trova in un’area urbana.", - "fr": "L'arbre est une zone urbaine." - } - }, - { - "if": { - "and": [ - "denotation=none" - ] - }, - "then": { - "nl": "De boom staat buiten een woonkern.", - "en": "The tree is outside of an urban area.", - "it": "L’albero si trova fuori dall’area urbana.", - "fr": "Cet arbre est en zone rurale." - } - } - ] - }, - { - "question": { - "nl": "Is deze boom groenblijvend of bladverliezend?", - "en": "Is this tree evergreen or deciduous?", - "it": "È un sempreverde o caduco?", - "ru": "Это дерево вечнозелёное или листопадное?", - "fr": "L’arbre est-il à feuillage persistant ou caduc ?" - }, - "mappings": [ - { - "if": { - "and": [ - "leaf_cycle=deciduous" - ] - }, - "then": { - "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", - "en": "Deciduous: the tree loses its leaves for some time of the year.", - "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno.", - "ru": "Листопадное: у дерева опадают листья в определённое время года.", - "fr": "Caduc : l’arbre perd son feuillage une partie de l’année." - } - }, - { - "if": { - "and": [ - "leaf_cycle=evergreen" - ] - }, - "then": { - "nl": "Groenblijvend.", - "en": "Evergreen.", - "it": "Sempreverde.", - "fr": "À feuilles persistantes.", - "ru": "Вечнозелёное." - } - } - ], - "condition": { - "and": [ - "leaf_type!~^leafless$" - ] - } - }, - { - "render": { - "nl": "Naam: {name}", - "en": "Name: {name}", - "it": "Nome: {name}", - "ru": "Название: {name}", - "fr": "Nom : {name}", - "id": "Nama: {name}" - }, - "question": { - "nl": "Heeft de boom een naam?", - "en": "Does the tree have a name?", - "it": "L’albero ha un nome?", - "fr": "L'arbre a-t-il un nom ?", - "ru": "Есть ли у этого дерева название?" - }, - "freeform": { - "key": "name", - "addExtraTags": [ - "noname=" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "name=", - "noname=yes" - ] - }, - "then": { - "nl": "De boom heeft geen naam.", - "en": "The tree does not have a name.", - "it": "L’albero non ha un nome.", - "fr": "L'arbre n'a pas de nom.", - "ru": "У этого дерева нет названия." - } - } - ], - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument", - "name~*" - ] - } - }, - { - "question": { - "nl": "Is deze boom erkend als erfgoed?", - "en": "Is this tree registered heritage?", - "it": "Quest’albero è registrato come patrimonio?", - "fr": "Cet arbre est-il inscrit au patrimoine ?" - }, - "mappings": [ - { - "if": { - "and": [ - "heritage=4", - "heritage:operator=OnroerendErfgoed" - ] - }, - "then": { - "nl": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen", - "en": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders", - "it": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders", - "fr": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" - } - }, - { - "if": { - "and": [ - "heritage=4", - "heritage:operator=aatl" - ] - }, - "then": { - "nl": "Erkend als natuurlijk erfgoed door Directie Cultureel Erfgoed Brussel", - "en": "Registered as heritage by Direction du Patrimoine culturel Brussels", - "it": "Registrato come patrimonio da Direction du Patrimoine culturel di Bruxelles", - "fr": "Enregistré comme patrimoine par la Direction du Patrimoine culturel Bruxelles" - } - }, - { - "if": { - "and": [ - "heritage=yes", - "heritage:operator=" - ] - }, - "then": { - "nl": "Erkend als erfgoed door een andere organisatie", - "en": "Registered as heritage by a different organisation", - "it": "Registrato come patrimonio da un’organizzazione differente", - "fr": "Enregistré comme patrimoine par une autre organisation" - } - }, - { - "if": { - "and": [ - "heritage=no", - "heritage:operator=" - ] - }, - "then": { - "nl": "Niet erkend als erfgoed", - "en": "Not registered as heritage", - "it": "Non è registrato come patrimonio", - "fr": "Non enregistré comme patrimoine" - } - }, - { - "if": { - "and": [ - "heritage~*" - ] - }, - "then": { - "nl": "Erkend als erfgoed door een andere organisatie", - "en": "Registered as heritage by a different organisation", - "it": "Registrato come patrimonio da un’organizzazione differente", - "fr": "Enregistré comme patrimoine par une autre organisation" - }, - "hideInAnswer": true - } - ], - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument" - ] - } - }, - { - "render": { - "nl": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}", - "en": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "ru": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "fr": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" - }, - "question": { - "nl": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", - "en": "What is the ID issued by Onroerend Erfgoed Flanders?", - "it": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", - "fr": "Quel est son identifiant donné par Onroerend Erfgoed ?" - }, - "freeform": { - "key": "ref:OnroerendErfgoed", - "type": "nat" - }, - "condition": { - "and": [ - "heritage=4", - "heritage:operator=OnroerendErfgoed" - ] - } - }, - { - "render": { - "nl": "\"\"/ Wikidata: {wikidata}", - "en": "\"\"/ Wikidata: {wikidata}", - "it": "\"\"/ Wikidata: {wikidata}", - "ru": "\"\"/ Wikidata: {wikidata}", - "fr": "\"\"/ Wikidata : {wikidata}" - }, - "question": { - "nl": "Wat is het Wikidata-ID van deze boom?", - "en": "What is the Wikidata ID for this tree?", - "it": "Qual è l’ID Wikidata per questo albero?", - "fr": "Quel est l'identifiant Wikidata de cet arbre ?" - }, - "freeform": { - "key": "wikidata", - "type": "wikidata" - }, - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument", - "wikidata~*" - ] - } - } - ], - "icon": { - "render": "circle:#ffffff;./assets/themes/trees/unknown.svg", - "mappings": [ - { - "if": { - "and": [ - "leaf_type=broadleaved" - ] - }, - "then": "circle:#ffffff;./assets/themes/trees/broadleaved.svg" - }, - { - "if": { - "and": [ - "leaf_type=needleleaved" - ] - }, - "then": "circle:#ffffff;./assets/themes/trees/needleleaved.svg" - } - ] - }, - "wayHandling": 1, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,bottom" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "natural=tree", - "leaf_type=broadleaved" - ], - "title": { - "nl": "Loofboom", - "en": "Broadleaved tree", - "it": "Albero latifoglia", - "fr": "Arbre feuillu", - "ru": "Лиственное дерево" - }, - "description": { - "nl": "Een boom van een soort die blaadjes heeft, bijvoorbeeld eik of populier.", - "en": "A tree of a species with leaves, such as oak or populus.", - "it": "Un albero di una specie con foglie larghe come la quercia o il pioppo.", - "fr": "Un arbre d'une espèce avec de larges feuilles, comme le chêne ou le peuplier." - } - }, - { - "tags": [ - "natural=tree", - "leaf_type=needleleaved" - ], - "title": { - "nl": "Naaldboom", - "en": "Needleleaved tree", - "it": "Albero aghifoglia", - "ru": "Хвойное дерево", - "fr": "Arbre résineux" - }, - "description": { - "nl": "Een boom van een soort met naalden, bijvoorbeeld den of spar.", - "en": "A tree of a species with needles, such as pine or spruce.", - "it": "Un albero di una specie con aghi come il pino o l’abete.", - "ru": "Дерево с хвоей (иглами), например, сосна или ель.", - "fr": "Une espèce d’arbre avec des épines comme le pin ou l’épicéa." - } - }, - { - "tags": [ - "natural=tree" - ], - "title": { + "id": "tree_node", + "name": { "nl": "Boom", "en": "Tree", "it": "Albero", "ru": "Дерево", - "fr": "Arbre", - "id": "Pohon" - }, - "description": { - "nl": "Wanneer je niet zeker bent of het nu een loof- of naaldboom is.", - "en": "If you're not sure whether it's a broadleaved or needleleaved tree.", - "it": "Qualora non si sia sicuri se si tratta di un albero latifoglia o aghifoglia.", - "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles.", - "ru": "Если вы не уверены в том, лиственное это дерево или хвойное." - } - } - ] + "fr": "Arbre" + }, + "minzoom": 16, + "source": { + "osmTags": { + "and": [ + "natural=tree" + ] + } + }, + "title": { + "render": { + "nl": "Boom", + "en": "Tree", + "it": "Albero", + "ru": "Дерево", + "fr": "Arbre" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}", + "en": "{name}", + "ca": "{name}", + "de": "{name}", + "fr": "{name}", + "it": "{name}", + "ru": "{name}", + "id": "{name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "id": "tree-height", + "render": { + "nl": "Hoogte: {height}", + "en": "Height: {height}", + "it": "Altezza: {height}", + "ru": "Высота: {height}", + "fr": "Hauteur : {height}" + }, + "condition": { + "and": [ + "height~*" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "height~^[0-9.]+$" + ] + }, + "then": { + "nl": "Hoogte: {height} m", + "en": "Height: {height} m", + "it": "Altezza: {height} m", + "ru": "Высота: {height} м", + "fr": "Hauteur : {height} m" + } + } + ] + }, + { + "id": "tree-leaf_type", + "question": { + "nl": "Is dit een naald- of loofboom?", + "en": "Is this a broadleaved or needleleaved tree?", + "it": "Si tratta di un albero latifoglia o aghifoglia?", + "fr": "Cet arbre est-il un feuillu ou un résineux ?" + }, + "mappings": [ + { + "if": { + "and": [ + "leaf_type=broadleaved" + ] + }, + "then": { + "nl": "\"\"/ Loofboom", + "en": "\"\"/ Broadleaved", + "it": "\"\"/ Latifoglia", + "fr": "\"\"/ Feuillu" + } + }, + { + "if": { + "and": [ + "leaf_type=needleleaved" + ] + }, + "then": { + "nl": "\"\"/ Naaldboom", + "en": "\"\"/ Needleleaved", + "it": "\"\"/ Aghifoglia", + "fr": "\"\"/ Résineux" + } + }, + { + "if": { + "and": [ + "leaf_type=leafless" + ] + }, + "then": { + "nl": "\"\"/ Permanent bladloos", + "en": "\"\"/ Permanently leafless", + "it": "\"\"/ Privo di foglie (permanente)", + "fr": "\"\"/ Sans feuilles (Permanent)" + }, + "hideInAnswer": true + } + ] + }, + { + "id": "tree-denotation", + "question": { + "nl": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is.", + "en": "How significant is this tree? Choose the first answer that applies.", + "it": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde.", + "fr": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." + }, + "mappings": [ + { + "if": { + "and": [ + "denotation=landmark" + ] + }, + "then": { + "nl": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie.", + "en": "The tree is remarkable due to its size or prominent location. It is useful for navigation.", + "it": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione.", + "fr": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." + } + }, + { + "if": { + "and": [ + "denotation=natural_monument" + ] + }, + "then": { + "nl": "De boom is een natuurlijk monument, bijvoorbeeld doordat hij bijzonder oud of van een waardevolle soort is.", + "en": "The tree is a natural monument, e.g. because it is especially old, or of a valuable species.", + "it": "L’albero è un monumento naturale, ad esempio perché specialmente antico o appartenente a specie importanti.", + "fr": "Cet arbre est un monument naturel (ex : âge, espèce, etc…)" + } + }, + { + "if": { + "and": [ + "denotation=agricultural" + ] + }, + "then": { + "nl": "De boom wordt voor landbouwdoeleinden gebruikt, bijvoorbeeld in een boomgaard.", + "en": "The tree is used for agricultural purposes, e.g. in an orchard.", + "it": "L’albero è usato per scopi agricoli, ad esempio in un frutteto.", + "fr": "Cet arbre est utilisé à but d’agriculture (ex : dans un verger)" + } + }, + { + "if": { + "and": [ + "denotation=park" + ] + }, + "then": { + "nl": "De boom staat in een park of dergelijke (begraafplaats, schoolterrein, …).", + "en": "The tree is in a park or similar (cemetery, school grounds, …).", + "it": "L’albero è in un parco o qualcosa di simile (cimitero, aree didattiche, etc.).", + "fr": "Cet arbre est dans un parc ou une aire similaire (ex : cimetière, cour d’école, …)." + } + }, + { + "if": { + "and": [ + "denotation=garden" + ] + }, + "then": { + "nl": "De boom staat in de tuin bij een woning/flatgebouw.", + "en": "The tree is a residential garden.", + "it": "L’albero è un giardino residenziale.", + "fr": "Cet arbre est dans une cour résidentielle." + } + }, + { + "if": { + "and": [ + "denotation=avenue" + ] + }, + "then": { + "nl": "Dit is een laanboom.", + "en": "This is a tree along an avenue.", + "it": "Fa parte di un viale alberato.", + "fr": "C'est un arbre le long d'une avenue." + } + }, + { + "if": { + "and": [ + "denotation=urban" + ] + }, + "then": { + "nl": "De boom staat in een woonkern.", + "en": "The tree is an urban area.", + "it": "L’albero si trova in un’area urbana.", + "fr": "L'arbre est une zone urbaine." + } + }, + { + "if": { + "and": [ + "denotation=none" + ] + }, + "then": { + "nl": "De boom staat buiten een woonkern.", + "en": "The tree is outside of an urban area.", + "it": "L’albero si trova fuori dall’area urbana.", + "fr": "Cet arbre est en zone rurale." + } + } + ] + }, + { + "id": "tree-decidouous", + "question": { + "nl": "Is deze boom groenblijvend of bladverliezend?", + "en": "Is this tree evergreen or deciduous?", + "it": "È un sempreverde o caduco?", + "ru": "Это дерево вечнозелёное или листопадное?", + "fr": "L’arbre est-il à feuillage persistant ou caduc ?" + }, + "mappings": [ + { + "if": { + "and": [ + "leaf_cycle=deciduous" + ] + }, + "then": { + "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", + "en": "Deciduous: the tree loses its leaves for some time of the year.", + "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno.", + "ru": "Листопадное: у дерева опадают листья в определённое время года.", + "fr": "Caduc : l’arbre perd son feuillage une partie de l’année." + } + }, + { + "if": { + "and": [ + "leaf_cycle=evergreen" + ] + }, + "then": { + "nl": "Groenblijvend.", + "en": "Evergreen.", + "it": "Sempreverde.", + "fr": "À feuilles persistantes.", + "ru": "Вечнозелёное." + } + } + ], + "condition": { + "and": [ + "leaf_type!~^leafless$" + ] + } + }, + { + "render": { + "nl": "Naam: {name}", + "en": "Name: {name}", + "it": "Nome: {name}", + "ru": "Название: {name}", + "fr": "Nom : {name}", + "id": "Nama: {name}" + }, + "question": { + "nl": "Heeft de boom een naam?", + "en": "Does the tree have a name?", + "it": "L’albero ha un nome?", + "fr": "L'arbre a-t-il un nom ?", + "ru": "Есть ли у этого дерева название?" + }, + "freeform": { + "key": "name", + "addExtraTags": [ + "noname=" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "name=", + "noname=yes" + ] + }, + "then": { + "nl": "De boom heeft geen naam.", + "en": "The tree does not have a name.", + "it": "L’albero non ha un nome.", + "fr": "L'arbre n'a pas de nom.", + "ru": "У этого дерева нет названия." + } + } + ], + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument", + "name~*" + ] + }, + "id": "tree_node-name" + }, + { + "id": "tree-heritage", + "question": { + "nl": "Is deze boom erkend als erfgoed?", + "en": "Is this tree registered heritage?", + "it": "Quest’albero è registrato come patrimonio?", + "fr": "Cet arbre est-il inscrit au patrimoine ?" + }, + "mappings": [ + { + "if": { + "and": [ + "heritage=4", + "heritage:operator=OnroerendErfgoed" + ] + }, + "then": { + "nl": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen", + "en": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders", + "it": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders", + "fr": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" + } + }, + { + "if": { + "and": [ + "heritage=4", + "heritage:operator=aatl" + ] + }, + "then": { + "nl": "Erkend als natuurlijk erfgoed door Directie Cultureel Erfgoed Brussel", + "en": "Registered as heritage by Direction du Patrimoine culturel Brussels", + "it": "Registrato come patrimonio da Direction du Patrimoine culturel di Bruxelles", + "fr": "Enregistré comme patrimoine par la Direction du Patrimoine culturel Bruxelles" + } + }, + { + "if": { + "and": [ + "heritage=yes", + "heritage:operator=" + ] + }, + "then": { + "nl": "Erkend als erfgoed door een andere organisatie", + "en": "Registered as heritage by a different organisation", + "it": "Registrato come patrimonio da un’organizzazione differente", + "fr": "Enregistré comme patrimoine par une autre organisation" + } + }, + { + "if": { + "and": [ + "heritage=no", + "heritage:operator=" + ] + }, + "then": { + "nl": "Niet erkend als erfgoed", + "en": "Not registered as heritage", + "it": "Non è registrato come patrimonio", + "fr": "Non enregistré comme patrimoine" + } + }, + { + "if": { + "and": [ + "heritage~*" + ] + }, + "then": { + "nl": "Erkend als erfgoed door een andere organisatie", + "en": "Registered as heritage by a different organisation", + "it": "Registrato come patrimonio da un’organizzazione differente", + "fr": "Enregistré comme patrimoine par une autre organisation" + }, + "hideInAnswer": true + } + ], + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument" + ] + } + }, + { + "render": { + "nl": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}", + "en": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "ru": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "fr": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" + }, + "question": { + "nl": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", + "en": "What is the ID issued by Onroerend Erfgoed Flanders?", + "it": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", + "fr": "Quel est son identifiant donné par Onroerend Erfgoed ?" + }, + "freeform": { + "key": "ref:OnroerendErfgoed", + "type": "nat" + }, + "condition": { + "and": [ + "heritage=4", + "heritage:operator=OnroerendErfgoed" + ] + }, + "id": "tree_node-ref:OnroerendErfgoed" + }, + { + "render": { + "nl": "\"\"/ Wikidata: {wikidata}", + "en": "\"\"/ Wikidata: {wikidata}", + "it": "\"\"/ Wikidata: {wikidata}", + "ru": "\"\"/ Wikidata: {wikidata}", + "fr": "\"\"/ Wikidata : {wikidata}" + }, + "question": { + "nl": "Wat is het Wikidata-ID van deze boom?", + "en": "What is the Wikidata ID for this tree?", + "it": "Qual è l’ID Wikidata per questo albero?", + "fr": "Quel est l'identifiant Wikidata de cet arbre ?" + }, + "freeform": { + "key": "wikidata", + "type": "wikidata" + }, + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument", + "wikidata~*" + ] + }, + "id": "tree_node-wikidata" + } + ], + "icon": { + "render": "circle:#ffffff;./assets/themes/trees/unknown.svg", + "mappings": [ + { + "if": { + "and": [ + "leaf_type=broadleaved" + ] + }, + "then": "circle:#ffffff;./assets/themes/trees/broadleaved.svg" + }, + { + "if": { + "and": [ + "leaf_type=needleleaved" + ] + }, + "then": "circle:#ffffff;./assets/themes/trees/needleleaved.svg" + } + ] + }, + "wayHandling": 1, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,bottom" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "natural=tree", + "leaf_type=broadleaved" + ], + "title": { + "nl": "Loofboom", + "en": "Broadleaved tree", + "it": "Albero latifoglia", + "fr": "Arbre feuillu", + "ru": "Лиственное дерево" + }, + "description": { + "nl": "Een boom van een soort die blaadjes heeft, bijvoorbeeld eik of populier.", + "en": "A tree of a species with leaves, such as oak or populus.", + "it": "Un albero di una specie con foglie larghe come la quercia o il pioppo.", + "fr": "Un arbre d'une espèce avec de larges feuilles, comme le chêne ou le peuplier." + } + }, + { + "tags": [ + "natural=tree", + "leaf_type=needleleaved" + ], + "title": { + "nl": "Naaldboom", + "en": "Needleleaved tree", + "it": "Albero aghifoglia", + "ru": "Хвойное дерево", + "fr": "Arbre résineux" + }, + "description": { + "nl": "Een boom van een soort met naalden, bijvoorbeeld den of spar.", + "en": "A tree of a species with needles, such as pine or spruce.", + "it": "Un albero di una specie con aghi come il pino o l’abete.", + "ru": "Дерево с хвоей (иглами), например, сосна или ель.", + "fr": "Une espèce d’arbre avec des épines comme le pin ou l’épicéa." + } + }, + { + "tags": [ + "natural=tree" + ], + "title": { + "nl": "Boom", + "en": "Tree", + "it": "Albero", + "ru": "Дерево", + "fr": "Arbre", + "id": "Pohon" + }, + "description": { + "nl": "Wanneer je niet zeker bent of het nu een loof- of naaldboom is.", + "en": "If you're not sure whether it's a broadleaved or needleleaved tree.", + "it": "Qualora non si sia sicuri se si tratta di un albero latifoglia o aghifoglia.", + "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles.", + "ru": "Если вы не уверены в том, лиственное это дерево или хвойное." + } + } + ] } \ No newline at end of file diff --git a/assets/layers/viewpoint/viewpoint.json b/assets/layers/viewpoint/viewpoint.json index f231df77b..6f34c3159 100644 --- a/assets/layers/viewpoint/viewpoint.json +++ b/assets/layers/viewpoint/viewpoint.json @@ -1,73 +1,74 @@ { - "id": "viewpoint", - "name": { - "en": "Viewpoint", - "nl": "Uitzicht", - "de": "Aussichtspunkt", - "fr": "Point de vue", - "it": "Punto panoramico", - "ru": "Смотровая площадка", - "id": "Sudut pandang" - }, - "description": { - "en": "A nice viewpoint or nice view. Ideal to add an image if no other category fits", - "nl": "Een mooi uitzicht - ideaal om een foto toe te voegen wanneer iets niet in een andere categorie past", - "de": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt", - "fr": "Un beau point de vue ou une belle vue. Idéal pour ajouter une image si aucune autre catégorie ne convient", - "it": "Un punto panoramico che offre una bella vista. L'ideale è aggiungere un'immagine, se nessun'altra categoria è appropriata" - }, - "source": { - "osmTags": "tourism=viewpoint" - }, - "minzoom": 14, - "icon": "./assets/layers/viewpoint/viewpoint.svg", - "iconSize": "20,20,center", - "color": "#ffffff", - "width": "5", - "wayhandling": 2, - "presets": [ - { - "title": { + "id": "viewpoint", + "name": { "en": "Viewpoint", "nl": "Uitzicht", "de": "Aussichtspunkt", "fr": "Point de vue", - "ru": "Смотровая площадка", "it": "Punto panoramico", + "ru": "Смотровая площадка", "id": "Sudut pandang" - }, - "tags": [ - "tourism=viewpoint" - ] - } - ], - "title": { - "render": { - "en": "Viewpoint", - "nl": "Uitzicht", - "de": "Aussichtspunkt", - "fr": "Point de vue", - "ru": "Смотровая площадка", - "it": "Punto panoramico", - "id": "Sudut pandang" - } - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "Do you want to add a description?", - "nl": "Zijn er bijzonderheden die je wilt toevoegen?", - "de": "Möchten Sie eine Beschreibung hinzufügen?", - "ru": "Вы хотите добавить описание?", - "fr": "Voulez-vous ajouter une description ?", - "it": "Vuoi aggiungere una descrizione?", - "id": "Apakah Anda ingin menambahkan deskripsi?" - }, - "render": "{description}", - "freeform": { - "key": "description" - } - } - ] + }, + "description": { + "en": "A nice viewpoint or nice view. Ideal to add an image if no other category fits", + "nl": "Een mooi uitzicht - ideaal om een foto toe te voegen wanneer iets niet in een andere categorie past", + "de": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt", + "fr": "Un beau point de vue ou une belle vue. Idéal pour ajouter une image si aucune autre catégorie ne convient", + "it": "Un punto panoramico che offre una bella vista. L'ideale è aggiungere un'immagine, se nessun'altra categoria è appropriata" + }, + "source": { + "osmTags": "tourism=viewpoint" + }, + "minzoom": 14, + "icon": "./assets/layers/viewpoint/viewpoint.svg", + "iconSize": "20,20,center", + "color": "#ffffff", + "width": "5", + "wayhandling": 2, + "presets": [ + { + "title": { + "en": "Viewpoint", + "nl": "Uitzicht", + "de": "Aussichtspunkt", + "fr": "Point de vue", + "ru": "Смотровая площадка", + "it": "Punto panoramico", + "id": "Sudut pandang" + }, + "tags": [ + "tourism=viewpoint" + ] + } + ], + "title": { + "render": { + "en": "Viewpoint", + "nl": "Uitzicht", + "de": "Aussichtspunkt", + "fr": "Point de vue", + "ru": "Смотровая площадка", + "it": "Punto panoramico", + "id": "Sudut pandang" + } + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "Do you want to add a description?", + "nl": "Zijn er bijzonderheden die je wilt toevoegen?", + "de": "Möchten Sie eine Beschreibung hinzufügen?", + "ru": "Вы хотите добавить описание?", + "fr": "Voulez-vous ajouter une description ?", + "it": "Vuoi aggiungere una descrizione?", + "id": "Apakah Anda ingin menambahkan deskripsi?" + }, + "render": "{description}", + "freeform": { + "key": "description" + }, + "id": "viewpoint-description" + } + ] } \ No newline at end of file diff --git a/assets/layers/village_green/village_green.json b/assets/layers/village_green/village_green.json index 02dc02293..9aa60fca4 100644 --- a/assets/layers/village_green/village_green.json +++ b/assets/layers/village_green/village_green.json @@ -1,37 +1,39 @@ { - "id": "village_green", - "name": { - "nl": "Speelweide" - }, - "source": { - "osmTags": "landuse=village_green" - }, - "minzoom": 0, - "title": { - "render": { - "nl": "Speelweide" + "id": "village_green", + "name": { + "nl": "Speelweide" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "source": { + "osmTags": "landuse=village_green" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + } + ] + }, + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,center", + "width": "1", + "color": "#937f20", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "id": "village_green-explanation", + "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." + }, + { + "id": "village_green-reviews", + "render": "{reviews(name, landuse=village_green )}" } - } ] - }, - "icon": "./assets/themes/playgrounds/playground.svg", - "iconSize": "40,40,center", - "width": "1", - "color": "#937f20", - "wayHandling": 2, - "tagRenderings": [ - "images", - { - "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." - }, - { - "render": "{reviews(name, landuse=village_green )}" - } - ] } \ No newline at end of file diff --git a/assets/layers/visitor_information_centre/visitor_information_centre.json b/assets/layers/visitor_information_centre/visitor_information_centre.json index 10c3cd0de..1f066376a 100644 --- a/assets/layers/visitor_information_centre/visitor_information_centre.json +++ b/assets/layers/visitor_information_centre/visitor_information_centre.json @@ -1,65 +1,65 @@ { - "id": "visitor_information_centre", - "name": { - "en": "Visitor Information Centre", - "nl": "Bezoekerscentrum" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "information=visitor_centre", - "information=office" - ] - } - ] - } - }, - "title": { - "render": { - "nl": "{name}", - "en": "{name}" + "id": "visitor_information_centre", + "name": { + "en": "Visitor Information Centre", + "nl": "Bezoekerscentrum" }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] - }, - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "information=visitor_centre", + "information=office" + ] + } + ] } - }, - { - "if": { - "and": [ - "name~*" - ] + }, + "title": { + "render": { + "nl": "{name}", + "en": "{name}" }, - "then": { - "nl": "{name}", - "en": "{name}" - } - } - ] - }, - "description": { - "en": "A visitor center offers information about a specific attraction or place of interest where it is located.", - "nl": "Een bezoekerscentrum biedt informatie over een specifieke attractie of bezienswaardigheid waar het is gevestigd." - }, - "tagRenderings": [], - "icon": { - "render": "./assets/layers/visitor_information_centre/information.svg" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#E64C00" - }, - "presets": [], - "wayHandling": 1 + "mappings": [ + { + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}", + "en": "{name}" + } + } + ] + }, + "description": { + "en": "A visitor center offers information about a specific attraction or place of interest where it is located.", + "nl": "Een bezoekerscentrum biedt informatie over een specifieke attractie of bezienswaardigheid waar het is gevestigd." + }, + "tagRenderings": [], + "icon": { + "render": "./assets/layers/visitor_information_centre/information.svg" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#E64C00" + }, + "presets": [], + "wayHandling": 1 } \ No newline at end of file diff --git a/assets/layers/waste_basket/waste_basket.json b/assets/layers/waste_basket/waste_basket.json index 1dd17348b..1cd888dcd 100644 --- a/assets/layers/waste_basket/waste_basket.json +++ b/assets/layers/waste_basket/waste_basket.json @@ -1,118 +1,119 @@ { - "id": "waste_basket", - "name": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - }, - "minzoom": 17, - "source": { - "osmTags": { - "and": [ - "amenity=waste_basket" - ] - } - }, - "title": { - "render": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - } - }, - "description": { - "en": "This is a public waste basket, thrash can, where you can throw away your thrash.", - "nl": "Dit is een publieke vuilnisbak waar je je afval kan weggooien." - }, - "tagRenderings": [ - { - "question": { - "en": "What kind of waste basket is this?", - "nl": "Wat voor soort vuilnisbak is dit?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "waste=", - "then": { - "en": "A waste basket for general waste", - "nl": "Een vuilnisbak voor zwerfvuil" - }, - "hideInAnswer": true - }, - { - "if": "waste=trash", - "then": { - "en": "A waste basket for general waste", - "nl": "Een vuilnisbak voor zwerfvuil" - } - }, - { - "if": "waste=dog_excrement", - "then": { - "en": "A waste basket for dog excrements", - "nl": "Een vuilnisbak specifiek voor hondenuitwerpselen" - } - }, - { - "if": "waste=cigarettes", - "then": { - "en": "A waste basket for cigarettes", - "nl": "Een vuilnisbak voor sigarettenpeuken" - } - }, - { - "if": "waste=drugs", - "then": { - "en": "A waste basket for drugs", - "nl": "Een vuilnisbak voor (vervallen) medicatie en drugs" - } - }, - { - "if": "waste=sharps", - "then": { - "en": "A waste basket for needles and other sharp objects", - "nl": "Een vuilnisbak voor injectienaalden en andere scherpe voorwerpen" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/waste_basket/waste_basket.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center", - "mappings": [ - { - "if": { - "and": [ - "amenity=waste_basket" - ] - }, - "then": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - } - } - ] - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=waste_basket" - ], - "title": { + "id": "waste_basket", + "name": { "en": "Waste Basket", "nl": "Vuilnisbak" - }, - "presiceInput": { - "preferredBackground": "photo" - } - } - ] + }, + "minzoom": 17, + "source": { + "osmTags": { + "and": [ + "amenity=waste_basket" + ] + } + }, + "title": { + "render": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + } + }, + "description": { + "en": "This is a public waste basket, thrash can, where you can throw away your thrash.", + "nl": "Dit is een publieke vuilnisbak waar je je afval kan weggooien." + }, + "tagRenderings": [ + { + "id": "waste-basket-waste-types", + "question": { + "en": "What kind of waste basket is this?", + "nl": "Wat voor soort vuilnisbak is dit?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "waste=", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + }, + "hideInAnswer": true + }, + { + "if": "waste=trash", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + } + }, + { + "if": "waste=dog_excrement", + "then": { + "en": "A waste basket for dog excrements", + "nl": "Een vuilnisbak specifiek voor hondenuitwerpselen" + } + }, + { + "if": "waste=cigarettes", + "then": { + "en": "A waste basket for cigarettes", + "nl": "Een vuilnisbak voor sigarettenpeuken" + } + }, + { + "if": "waste=drugs", + "then": { + "en": "A waste basket for drugs", + "nl": "Een vuilnisbak voor (vervallen) medicatie en drugs" + } + }, + { + "if": "waste=sharps", + "then": { + "en": "A waste basket for needles and other sharp objects", + "nl": "Een vuilnisbak voor injectienaalden en andere scherpe voorwerpen" + } + } + ] + } + ], + "icon": { + "render": "./assets/themes/waste_basket/waste_basket.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center", + "mappings": [ + { + "if": { + "and": [ + "amenity=waste_basket" + ] + }, + "then": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + } + } + ] + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=waste_basket" + ], + "title": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + }, + "presiceInput": { + "preferredBackground": "photo" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/watermill/watermill.json b/assets/layers/watermill/watermill.json index 02b74566e..6f8dcb65f 100644 --- a/assets/layers/watermill/watermill.json +++ b/assets/layers/watermill/watermill.json @@ -1,173 +1,173 @@ { - "id": "watermill", - "name": { - "nl": "watermolens", - "en": "Watermill" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=watermill" - ] - } - }, - "title": { - "render": { - "nl": "Watermolens" + "id": "watermill", + "name": { + "nl": "Watermolens", + "en": "Watermill" }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] - }, - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "man_made=watermill" + ] } - }, - { - "if": { - "and": [ - "name~*" - ] - }, - "then": { - "nl": "{name}" - } - } - ] - }, - "description": { - "nl": "Watermolens" - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit pad?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ + "title": { + "render": { + "nl": "Watermolens" + }, + "mappings": [ + { + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } + } + ] + }, + "description": { + "nl": "Watermolens" + }, + "tagRenderings": [ + "images", { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } + ], + "id": "Access tag" }, { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit pad?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + } + ], + "id": "Operator tag" } - ] + ], + "wayHandling": 1, + "icon": { + "render": "./assets/layers/watermill/watermill.svg" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#FFC0CB" } - ], - "wayHandling": 1, - "icon": { - "render": "./assets/layers/watermill/watermill.svg" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#FFC0CB" - } } \ No newline at end of file diff --git a/assets/svg/hand.svg b/assets/svg/hand.svg index 75118da95..bbef4187a 100644 --- a/assets/svg/hand.svg +++ b/assets/svg/hand.svg @@ -1,53 +1,30 @@ - - - - image/svg+xml - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg6" + height="39.557907" + width="28.561806" + version="1.1"> + + + + image/svg+xml + + + + + + + diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index 30aab5b27..fb2e939bd 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -56,7 +56,8 @@ "de": "Was ist die Mail-Adresse von {name}?", "pt_BR": "Qual o endereço de e-mail de {name}?", "pl": "Jaki jest adres e-mail do {name}?", - "sv": "Vad är e-postadressen till {name}?" + "sv": "Vad är e-postadressen till {name}?", + "pt": "Qual é o endereço de e-mail de {name}?" }, "freeform": { "key": "email", @@ -184,7 +185,8 @@ "it": "C'è ancora qualche informazione importante che non è stato possibile fornire nelle domande precedenti? Aggiungila qui.
Non ripetere informazioni già fornite", "de": "Gibt es noch etwas, das die vorhergehenden Fragen nicht abgedeckt haben? Hier wäre Platz dafür.
Bitte keine bereits erhobenen Informationen.", "pl": "Czy jest jeszcze coś istotnego, czego nie mogłeś podać w poprzednich pytaniach? Dodaj to tutaj.
Nie powtarzaj już podanych faktów", - "pt_BR": "Ainda há algo de relevante que não pôde dar nas perguntas anteriores? Adicione aqui.
Não repita fatos já declarados" + "pt_BR": "Ainda há algo de relevante que não pôde dar nas perguntas anteriores? Adicione aqui.
Não repita fatos já declarados", + "pt": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" }, "render": "{description}", "freeform": { @@ -266,7 +268,8 @@ "fr": "À quel étage se situe l’élément ?", "pl": "Na jakim poziomie znajduje się ta funkcja?", "pt_BR": "Em que nível esse recurso está localizado?", - "ru": "На каком этаже находится этот объект?" + "ru": "На каком этаже находится этот объект?", + "pt": "Em que nível se encontra este elemento?" }, "render": { "en": "Located on the {level}th floor", @@ -294,7 +297,8 @@ "zh_Hant": "位於地下", "fr": "En sous-sol", "pl": "Znajduje się pod ziemią", - "sv": "Ligger under jorden" + "sv": "Ligger under jorden", + "pt": "Está no subsolo" }, "hideInAnswer": true }, @@ -309,7 +313,8 @@ "zh_Hant": "位於 1 樓", "fr": "Rez-de-chaussée", "pl": "Znajduje się na parterze", - "sv": "Ligger på bottenvåningen" + "sv": "Ligger på bottenvåningen", + "pt": "Está ao nível do rés-do-chão" } }, { @@ -324,7 +329,8 @@ "zh_Hant": "位於 1 樓", "fr": "Rez-de-chaussée", "pl": "Znajduje się na parterze", - "sv": "Ligger på bottenvåningen" + "sv": "Ligger på bottenvåningen", + "pt": "Está ao nível do rés-do-chão" } }, { @@ -338,7 +344,8 @@ "zh_Hant": "位於 2 樓", "fr": "Premier étage", "pl": "Znajduje się na pierwszym piętrze", - "sv": "Ligger på första våningen" + "sv": "Ligger på första våningen", + "pt": "Está no primeiro andar" } } ] diff --git a/assets/themes/artwork/artwork.json b/assets/themes/artwork/artwork.json index c02fc72fe..c03d7c023 100644 --- a/assets/themes/artwork/artwork.json +++ b/assets/themes/artwork/artwork.json @@ -342,7 +342,8 @@ "nb_NO": "Flisarbeid" } } - ] + ], + "id": "artwork-artwork_type" }, { "question": { @@ -369,7 +370,8 @@ }, "freeform": { "key": "artist_name" - } + }, + "id": "artwork-artist_name" }, { "question": { @@ -398,7 +400,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "artwork-website" }, { "question": { @@ -426,7 +429,8 @@ "freeform": { "key": "wikidata", "type": "wikidata" - } + }, + "id": "artwork-wikidata" } ] } diff --git a/assets/themes/benches/benches.json b/assets/themes/benches/benches.json index a43292dbf..d94f88597 100644 --- a/assets/themes/benches/benches.json +++ b/assets/themes/benches/benches.json @@ -52,7 +52,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "bench", diff --git a/assets/themes/bicyclelib/bicyclelib.json b/assets/themes/bicyclelib/bicyclelib.json index fe40e2d34..bc251907b 100644 --- a/assets/themes/bicyclelib/bicyclelib.json +++ b/assets/themes/bicyclelib/bicyclelib.json @@ -40,9 +40,14 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "roamingRenderings": [], "layers": [ - "bicycle_library" + { + "builtin": "bicycle_library", + "override": { + "minZoom": 0 + } + } ] } \ No newline at end of file diff --git a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json b/assets/themes/bike_monitoring_station/bike_monitoring_stations.json deleted file mode 100644 index 5703e2ed5..000000000 --- a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "id": "bike_monitoring_stations", - "title": { - "en": "Bike Monitoring stations", - "nl": "Fietstelstations", - "it": "Stazioni di monitoraggio biciclette", - "ru": "Станции мониторинга велосипедов", - "ja": "自転車監視ステーション", - "zh_Hant": "自行車監視站", - "fr": "Station de comptage vélo", - "pt_BR": "Estações de monitoramento de bicicletas" - }, - "shortDescription": { - "en": "Bike monitoring stations with live data from Brussels Mobility", - "nl": "Fietstelstations met live data van Brussel Mobiliteit", - "it": "Stazioni di monitoraggio bici con dati in tempo reale forniti da Bruxelles Mobility", - "ru": "Станции мониторинга велосипедов с оперативными данными от Brussels Mobility", - "ja": "Brussels Mobilityのライブデータを使用した自転車モニタリングステーション", - "zh_Hant": "布魯塞爾車行資料的即時單車監視站資料", - "fr": "Station de comptage vélo avec données en temps réel par Bruxelles Mobilités", - "pt_BR": "Estações de monitoramento de bicicletas com dados ao vivo da Mobilidade de Bruxelas" - }, - "description": { - "en": "This theme shows bike monitoring stations with live data", - "nl": "Dit thema toont fietstelstations met live data", - "it": "Questo tema mostra le stazioni di monitoraggio bici con dati dal vivo", - "ru": "В этой теме показаны станции мониторинга велосипедов с данными в реальном времени", - "ja": "このテーマでは、ライブデータのある自転車監視ステーションを示します", - "zh_Hant": "這個主題顯示單車監視站的即時資料", - "fr": "Ce thème montre les données des compteurs en temps réel", - "pt_BR": "Este tema mostra as estações de monitoramento de bicicletas com dados ao vivo" - }, - "language": [ - "en", - "nl", - "it", - "ru", - "ja", - "zh_Hant", - "fr", - "pt_BR" - ], - "hideFromOverview": true, - "maintainer": "", - "icon": "./assets/layers/bike_monitoring_station/monitoring_station.svg", - "version": "0", - "startLat": 50.8435, - "startLon": 4.3688, - "startZoom": 14, - "widenFactor": 0.05, - "socialImage": "", - "layers": [ - "bike_monitoring_station" - ], - "roamingRenderings": [], - "defaultBackgroundId": "Stadia.AlidadeSmoothDark" -} \ No newline at end of file diff --git a/assets/themes/binoculars/binoculars.json b/assets/themes/binoculars/binoculars.json index 0f9817e46..75622d3a5 100644 --- a/assets/themes/binoculars/binoculars.json +++ b/assets/themes/binoculars/binoculars.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "binocular" diff --git a/assets/themes/buurtnatuur/buurtnatuur.json b/assets/themes/buurtnatuur/buurtnatuur.json index 9c82e4d44..9c4f2a189 100644 --- a/assets/themes/buurtnatuur/buurtnatuur.json +++ b/assets/themes/buurtnatuur/buurtnatuur.json @@ -25,7 +25,7 @@ "startLat": 50.8435, "startLon": 4.3688, "startZoom": 16, - "widenFactor": 0.01, + "widenFactor": 1.2, "socialImage": "./assets/themes/buurtnatuur/social_image.jpg", "layers": [ { diff --git a/assets/themes/cafes_and_pubs/cafes_and_pubs.json b/assets/themes/cafes_and_pubs/cafes_and_pubs.json index 1f9b704f8..c7ec682d1 100644 --- a/assets/themes/cafes_and_pubs/cafes_and_pubs.json +++ b/assets/themes/cafes_and_pubs/cafes_and_pubs.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "cafe_pub" diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index 7b24124e5..f9951ed0a 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -47,7 +47,7 @@ "startLat": 43.14, "startLon": 3.14, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "./assets/themes/campersite/Bar%C3%9Fel_Wohnmobilstellplatz.jpg", "layers": [ { @@ -138,9 +138,11 @@ }, "freeform": { "key": "name" - } + }, + "id": "caravansites-name" }, { + "id": "caravansites-fee", "question": { "en": "Does this place charge a fee?", "it": "Ha una tariffa questo luogo?", @@ -226,9 +228,11 @@ "and": [ "fee=yes" ] - } + }, + "id": "caravansites-charge" }, { + "id": "caravansites-sanitary-dump", "question": { "en": "Does this place have a sanitary dump station?", "it": "Questo luogo ha una stazione per lo scarico delle acque?", @@ -295,9 +299,11 @@ "freeform": { "key": "capacity", "type": "pnat" - } + }, + "id": "caravansites-capacity" }, { + "id": "caravansites-internet", "question": { "en": "Does this place provide internet access?", "id": "Tempat ini berbagi akses Web?", @@ -365,6 +371,7 @@ ] }, { + "id": "caravansites-internet-fee", "question": { "en": "Do you have to pay for the internet access?", "it": "Occorre pagare per avere l’accesso a internet?", @@ -415,6 +422,7 @@ } }, { + "id": "caravansites-toilets", "question": { "en": "Does this place have toilets?", "it": "Questo luogo dispone di servizi igienici?", @@ -491,9 +499,11 @@ "zh_Hant": "這個地方有網站嗎?", "fr": "Ce lieu a-t’il un site internet ?", "pt_BR": "Este lugar tem um website?" - } + }, + "id": "caravansites-website" }, { + "id": "caravansites-long-term", "question": { "en": "Does this place offer spots for long term rental?", "ru": "Предлагает ли эта площадка места для долгосрочной аренды?", @@ -575,7 +585,8 @@ "freeform": { "key": "description", "type": "text" - } + }, + "id": "caravansites-description" }, "questions", "reviews" @@ -684,6 +695,7 @@ "tagRenderings": [ "images", { + "id": "dumpstations-fee", "question": { "en": "Does this place charge a fee?", "ru": "Взимается ли в этом месте плата?", @@ -749,9 +761,11 @@ "and": [ "fee=yes" ] - } + }, + "id": "dumpstations-charge" }, { + "id": "dumpstations-waterpoint", "question": { "en": "Does this place have a water point?", "ru": "Есть ли в этом месте водоснабжение?", @@ -794,6 +808,7 @@ ] }, { + "id": "dumpstations-grey-water", "question": { "en": "Can you dispose of grey water here?", "ru": "Можно ли здесь утилизировать серую воду?", @@ -833,6 +848,7 @@ ] }, { + "id": "dumpstations-chemical-waste", "question": { "en": "Can you dispose of chemical toilet waste here?", "ru": "Можно ли здесь утилизировать отходы химических туалетов?", @@ -875,6 +891,7 @@ ] }, { + "id": "dumpstations-access", "question": { "en": "Who can use this dump station?", "ja": "このゴミ捨て場は誰が使えるんですか?", @@ -957,7 +974,8 @@ }, "freeform": { "key": "network" - } + }, + "id": "dumpstations-network" } ], "icon": { diff --git a/assets/themes/charging_stations/charging_stations.json b/assets/themes/charging_stations/charging_stations.json index b193b4daf..16745dc60 100644 --- a/assets/themes/charging_stations/charging_stations.json +++ b/assets/themes/charging_stations/charging_stations.json @@ -39,7 +39,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "defaultBackgroundId": "CartoDB.Voyager", "layers": [ diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 44a2520db..edfa859fa 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -48,7 +48,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ { @@ -138,9 +138,11 @@ }, "freeform": { "key": "name" - } + }, + "id": "climbing_club-name" }, { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, "website", @@ -265,10 +267,10 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "name", "render": { "en": "{name}", "nl": "{name}", @@ -288,7 +290,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "name" }, "website", "phone", @@ -358,10 +361,10 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "Name", "render": { "en": "{name}", "nl": "{name}", @@ -401,10 +404,10 @@ "fr": "Cette voie n’a pas de nom" } } - ] + ], + "id": "Name" }, { - "#": "Length", "question": { "en": "How long is this climbing route (in meters)?", "nl": "Hoe lang is deze klimroute (in meters)?", @@ -423,10 +426,10 @@ "freeform": { "key": "climbing:length", "type": "pnat" - } + }, + "id": "Length" }, { - "#": "Difficulty", "question": { "en": "What is the difficulty of this climbing route according to the french/belgian system?", "nl": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", @@ -443,10 +446,10 @@ }, "freeform": { "key": "climbing:grade:french" - } + }, + "id": "Difficulty" }, { - "#": "Bolts", "question": { "en": "How much bolts does this route have before reaching the moulinette?", "fr": "Combien de prises cette voie possède avant d’atteindre la moulinette ?" @@ -478,25 +481,26 @@ "fr": "Cette voie n’a pas de prises" } } - ] + ], + "id": "Bolts" }, { - "#": "Description", "question": "Is there other relevant info?", "render": "

Description


{description}", "freeform": { "key": "description" - } + }, + "id": "Description" }, { - "#": "Rock type", "render": { "en": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag", "fr": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" }, "freeform": { "key": "_embedding_features_with_rock:rock" - } + }, + "id": "Rock type" }, "reviews" ], @@ -618,34 +622,34 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "Contained routes length hist", "render": { "en": "

Length overview

{histogram(_length_hist)}", "fr": "

Résumé de longueur

{histogram(_length_hist)}" }, - "condition": "_length_hist!~\\[\\]" + "condition": "_length_hist!~\\[\\]", + "id": "Contained routes length hist" }, { - "#": "Contained routes hist", "render": { "en": "

Difficulties overview

{histogram(_difficulty_hist)}", "fr": "

Résumé des difficultés

{histogram(_difficulty_hist)}" }, - "condition": "_difficulty_hist!~\\[\\]" + "condition": "_difficulty_hist!~\\[\\]", + "id": "Contained routes hist" }, { - "#": "Containe {_contained_climbing_routes_count} routes", "render": { "en": "

Contains {_contained_climbing_routes_count} routes

    {_contained_climbing_routes}
", "fr": "

Contient {_contained_climbing_routes_count} voies

    {_contained_climbing_routes}
" }, - "condition": "_contained_climbing_routes~*" + "condition": "_contained_climbing_routes~*", + "id": "Containe {_contained_climbing_routes_count} routes" }, { - "#": "name", "render": { "en": "{name}", "nl": "{name}", @@ -682,10 +686,10 @@ "fr": "Ce site n’a pas de nom" } } - ] + ], + "id": "name" }, { - "#": "Type", "question": "What kind of climbing opportunity is this?", "mappings": [ { @@ -706,10 +710,10 @@ "if": "climbing=area", "then": "A climbing area with one or more climbing crags and/or boulders" } - ] + ], + "id": "Type" }, { - "#": "Rock type (crag/rock/cliff only)", "question": { "en": "What is the rock type here?", "fr": "Quel est le type de roche ?" @@ -737,7 +741,8 @@ "natural=cliff", "natural=bare_rock" ] - } + }, + "id": "Rock type (crag/rock/cliff only)" }, "reviews" ], @@ -834,9 +839,11 @@ }, "tagRenderings": [ { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { + "id": "climbing-opportunity-name", "render": { "en": "{name}", "de": "{name}", @@ -850,6 +857,7 @@ "condition": "name~*" }, { + "id": "climbing-possible", "question": { "en": "Is climbing possible here?", "de": "Kann hier geklettert werden?", diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index 85a91aa7d..08b7c8556 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -21,7 +21,7 @@ "clustering": { "maxZoom": 1 }, - "widenFactor": 0.005, + "widenFactor": 1.1, "enableDownload": true, "enablePdfDownload": true, "layers": [ @@ -33,14 +33,16 @@ "question": "What is the name of this cycle highway?", "freeform": { "key": "name" - } + }, + "id": "cycle_highways-name" }, { "render": "Referentienummer is {ref}", "question": "What is the reference number of this cycle highway?", "freeform": { "key": "ref" - } + }, + "id": "cycle_highways-ref" }, { "render": "The current state of this link is {state}", @@ -84,15 +86,15 @@ "if": "state=", "then": "This link is operational and signposted" } - ] + ], + "id": "cycle_highways-state" }, { + "id": "cycle-highway-length", "render": "This part is {_length:km}km long" }, "website", - { - "render": "{all_tags()}" - } + "all_tags" ], "name": { "en": "cycle highways" @@ -141,6 +143,7 @@ }, "filter": [ { + "id": "name-alt", "options": [ { "question": "Name contains 'alt'", @@ -149,6 +152,7 @@ ] }, { + "id": "name-wenslijn", "options": [ { "question": "Name contains 'wenslijn'", @@ -157,6 +161,7 @@ ] }, { + "id": "name-omleiding", "options": [ { "question": "Name contains 'omleiding'", @@ -165,6 +170,7 @@ ] }, { + "id": "ref-alt", "options": [ { "question": "Reference contains 'alt'", @@ -173,6 +179,7 @@ ] }, { + "id": "missing_link", "options": [ { "question": "No filter" @@ -192,6 +199,7 @@ ] }, { + "id": "proposed", "options": [ { "question": "No filter" diff --git a/assets/themes/cycle_infra/cycle_infra.json b/assets/themes/cycle_infra/cycle_infra.json index 7446095d9..8af56b886 100644 --- a/assets/themes/cycle_infra/cycle_infra.json +++ b/assets/themes/cycle_infra/cycle_infra.json @@ -24,7 +24,7 @@ "startLat": 51, "startLon": 3.75, "startZoom": 11, - "widenFactor": 1, + "widenFactor": 1.5, "socialImage": "./assets/themes/cycle_infra/cycle-infra.svg", "enableDownload": true, "layers": [ diff --git a/assets/themes/cyclestreets/cyclestreets.json b/assets/themes/cyclestreets/cyclestreets.json index 45ad1a90c..39f75ac78 100644 --- a/assets/themes/cyclestreets/cyclestreets.json +++ b/assets/themes/cyclestreets/cyclestreets.json @@ -35,6 +35,10 @@ "startLon": 3.2228, "maintainer": "MapComplete", "widenfactor": 2, + "clustering": { + "maxZoom": 12, + "minNeededElements": 200 + }, "roamingRenderings": [ { "question": { diff --git a/assets/themes/cyclofix/cyclofix.json b/assets/themes/cyclofix/cyclofix.json index 2e1016d77..47a626736 100644 --- a/assets/themes/cyclofix/cyclofix.json +++ b/assets/themes/cyclofix/cyclofix.json @@ -40,7 +40,7 @@ "defaultBackgroundId": "CartoDB.Voyager", "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "assets/themes/cyclofix/logo.svg", "layers": [ "bike_cafe", diff --git a/assets/themes/facadegardens/facadegardens.json b/assets/themes/facadegardens/facadegardens.json index f3e28a1ef..bb3155e59 100644 --- a/assets/themes/facadegardens/facadegardens.json +++ b/assets/themes/facadegardens/facadegardens.json @@ -38,7 +38,7 @@ "startLat": 51.02768, "startLon": 4.480705, "startZoom": 15, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ { @@ -125,9 +125,11 @@ "freeform": { "type": "direction", "key": "direction" - } + }, + "id": "facadegardens-direction" }, { + "id": "facadegardens-sunshine", "mappings": [ { "if": { @@ -183,6 +185,7 @@ } }, { + "id": "facadegardens-rainbarrel", "question": { "nl": "Is er een regenton voorzien bij het tuintje?", "en": "Is there a water barrel installed for the garden?", @@ -241,9 +244,11 @@ "freeform": { "key": "start_date", "type": "text" - } + }, + "id": "facadegardens-start_date" }, { + "id": "facadegardens-edible", "mappings": [ { "if": { @@ -283,6 +288,7 @@ } }, { + "id": "facadegardens-plants", "question": { "nl": "Wat voor planten staan hier?", "en": "What kinds of plants grow here?", @@ -355,7 +361,8 @@ "freeform": { "key": "description", "type": "text" - } + }, + "id": "facadegardens-description" } ], "icon": { diff --git a/assets/themes/food/food.json b/assets/themes/food/food.json index 416f9d161..fed26b560 100644 --- a/assets/themes/food/food.json +++ b/assets/themes/food/food.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ "food" diff --git a/assets/themes/fritures/fritures.json b/assets/themes/fritures/fritures.json index 33d83c0f5..fec9038cc 100644 --- a/assets/themes/fritures/fritures.json +++ b/assets/themes/fritures/fritures.json @@ -24,7 +24,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { diff --git a/assets/themes/fruit_trees/fruit_trees.json b/assets/themes/fruit_trees/fruit_trees.json index 60d6e8a23..68ce79228 100644 --- a/assets/themes/fruit_trees/fruit_trees.json +++ b/assets/themes/fruit_trees/fruit_trees.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.001, + "widenFactor": 2, "socialImage": "", "hideFromOverview": true, "layers": [ @@ -101,7 +101,8 @@ }, "freeform": { "key": "species:nl" - } + }, + "id": "fruitboom-species:nl" }, { "render": { @@ -117,7 +118,8 @@ "and": [ "species:nl~*" ] - } + }, + "id": "fruitboom-taxon" }, { "render": { @@ -128,7 +130,8 @@ }, "freeform": { "key": "description" - } + }, + "id": "fruitboom-description" }, { "render": { @@ -139,7 +142,8 @@ }, "freeform": { "key": "ref" - } + }, + "id": "fruitboom-ref" } ], "icon": { diff --git a/assets/themes/ghostbikes/ghostbikes.json b/assets/themes/ghostbikes/ghostbikes.json index 229a32751..7c9aec38b 100644 --- a/assets/themes/ghostbikes/ghostbikes.json +++ b/assets/themes/ghostbikes/ghostbikes.json @@ -52,7 +52,7 @@ "startZoom": 1, "startLat": 0, "startLon": 0, - "widenFactor": 0.1, + "widenFactor": 5, "layers": [ "ghost_bike" ], diff --git a/assets/themes/grb.json b/assets/themes/grb.json index 37efacae0..a0f32cdc6 100644 --- a/assets/themes/grb.json +++ b/assets/themes/grb.json @@ -18,7 +18,7 @@ "startLat": 51.2132, "startLon": 3.231, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 2, "cacheTimeout": 3600, "socialImage": "", "layers": [ @@ -61,6 +61,7 @@ }, "tagRenderings": [ { + "id": "grb-housenumber", "render": { "nl": "Het huisnummer is {addr:housenumber}" }, @@ -112,6 +113,7 @@ ] }, { + "id": "grb-unit", "question": "Wat is de wooneenheid-aanduiding?", "render": { "nl": "De wooneenheid-aanduiding is {addr:unit} " @@ -127,6 +129,7 @@ ] }, { + "id": "grb-street", "render": { "nl": "De straat is {addr:street}" }, @@ -138,6 +141,7 @@ } }, { + "id": "grb-fixme", "render": { "nl": "De fixme is {fixme}" }, @@ -161,6 +165,7 @@ ] }, { + "id": "grb-min-level", "render": { "nl": "Dit gebouw begint maar op de {building:min_level} verdieping" }, diff --git a/assets/themes/hackerspaces/hackerspaces.json b/assets/themes/hackerspaces/hackerspaces.json index 538bc0414..5fd86804e 100644 --- a/assets/themes/hackerspaces/hackerspaces.json +++ b/assets/themes/hackerspaces/hackerspaces.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ { @@ -49,6 +49,7 @@ }, "tagRenderings": [ { + "id": "is_makerspace", "question": { "en": "Is this a hackerspace or a makerspace?" }, @@ -76,7 +77,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "hackerspaces-name" }, "website", "email", @@ -103,10 +105,12 @@ "en": "Opened 24/7" } } - ] + ], + "id": "hackerspaces-opening_hours" }, "wheelchair-access", { + "id": "hs-club-mate", "question": { "en": "Does this hackerspace serve Club Mate?" }, @@ -128,7 +132,7 @@ ] }, "then": { - "en": "This hackerspace is not worthy of the name hackerspace as it does not serve club mate" + "en": "This hackerspace does not serve club mate" } } ] @@ -143,7 +147,8 @@ "freeform": { "key": "start_date", "type": "date" - } + }, + "id": "hackerspaces-start_date" } ], "icon": { diff --git a/assets/themes/hailhydrant/hailhydrant.json b/assets/themes/hailhydrant/hailhydrant.json index c5cdd3795..3a94dbb1b 100644 --- a/assets/themes/hailhydrant/hailhydrant.json +++ b/assets/themes/hailhydrant/hailhydrant.json @@ -36,7 +36,7 @@ "startLat": 13.67801, "startLon": 121.6625, "startZoom": 6, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { @@ -76,6 +76,7 @@ }, "tagRenderings": [ { + "id": "hydrant-color", "question": { "en": "What color is the hydrant?", "ja": "消火栓の色は何色ですか?", @@ -138,6 +139,7 @@ ] }, { + "id": "hydrant-type", "question": { "en": "What type of hydrant is it?", "ja": "どんな消火栓なんですか?", @@ -224,6 +226,7 @@ ] }, { + "id": "hydrant-state", "question": { "en": "Update the lifecycle status of the hydrant.", "ja": "消火栓のライフサイクルステータスを更新します。", @@ -351,6 +354,7 @@ }, "tagRenderings": [ { + "id": "extinguisher-location", "render": { "en": "Location: {location}", "ja": "場所:{location}", @@ -469,6 +473,7 @@ }, "tagRenderings": [ { + "id": "station-name", "freeform": { "key": "name" }, @@ -488,6 +493,7 @@ } }, { + "id": "station-street", "freeform": { "key": "addr:street" }, @@ -506,6 +512,7 @@ } }, { + "id": "station-place", "question": { "en": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", "ja": "このステーションの住所は?(例: 地区、村、または町の名称)", @@ -523,6 +530,7 @@ } }, { + "id": "station-agency", "question": { "en": "What agency operates this station?", "ja": "このステーションを運営しているのはどこですか?", @@ -553,6 +561,7 @@ ] }, { + "id": "station-operator", "question": { "en": "How is the station operator classified?", "ja": "ステーションの運営の分類は?", @@ -681,6 +690,7 @@ }, "tagRenderings": [ { + "id": "ambulance-name", "freeform": { "key": "name" }, @@ -698,6 +708,7 @@ } }, { + "id": "ambulance-street", "freeform": { "key": "addr:street" }, @@ -715,6 +726,7 @@ } }, { + "id": "ambulance-place", "question": { "en": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", "ja": "このステーションの住所は?(例: 地区、村、または町の名称)", @@ -731,6 +743,7 @@ } }, { + "id": "ambulance-agency", "question": { "en": "What agency operates this station?", "ja": "このステーションを運営しているのはどこですか?", @@ -747,6 +760,7 @@ "mappings": [] }, { + "id": "ambulance-operator-type", "question": { "en": "How is the station operator classified?", "ja": "ステーションの運営の分類は?", diff --git a/assets/themes/maps/maps.json b/assets/themes/maps/maps.json index e34cdce30..52d757a9d 100644 --- a/assets/themes/maps/maps.json +++ b/assets/themes/maps/maps.json @@ -36,7 +36,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "map" diff --git a/assets/themes/nature/nature.json b/assets/themes/nature/nature.json index 9aeb9e498..0f8004e2c 100644 --- a/assets/themes/nature/nature.json +++ b/assets/themes/nature/nature.json @@ -18,7 +18,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ "drinking_water", diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index 4616fae02..7ebcab3b5 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -23,12 +23,16 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 15, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "CartoDB.Positron", "enablePdfDownload": true, "enableDownload": true, "hideFromOverview": true, + "clustering": { + "#": "Disable clustering for this theme", + "maxZoom": 0 + }, "layers": [ { "#": "Nature reserve with geometry, z>=13", @@ -70,7 +74,8 @@ "minzoom": 1, "icon": { "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg" - } + }, + "presets": [] } }, { diff --git a/assets/themes/observation_towers/observation_towers.json b/assets/themes/observation_towers/observation_towers.json index 2bdd0cbad..3ab5a6b58 100644 --- a/assets/themes/observation_towers/observation_towers.json +++ b/assets/themes/observation_towers/observation_towers.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "observation_tower" diff --git a/assets/themes/openwindpowermap/openwindpowermap.json b/assets/themes/openwindpowermap/openwindpowermap.json index b82db0942..a437a06bd 100644 --- a/assets/themes/openwindpowermap/openwindpowermap.json +++ b/assets/themes/openwindpowermap/openwindpowermap.json @@ -63,6 +63,7 @@ }, "tagRenderings": [ { + "id": "turbine-output", "render": { "en": "The power output of this wind turbine is {generator:output:electricity}.", "fr": "La puissance générée par cette éolienne est de {generator:output:electricity}." @@ -77,6 +78,7 @@ } }, { + "id": "turbine-operator", "render": { "en": "This wind turbine is operated by {operator}.", "fr": "Cette éolienne est opérée par {operator}." @@ -90,6 +92,7 @@ } }, { + "id": "turbine-height", "render": { "en": "The total height (including rotor radius) of this wind turbine is {height} metres.", "fr": "La hauteur totale, incluant les pales, est de {height} mètres." @@ -104,6 +107,7 @@ } }, { + "id": "turbine-diameter", "render": { "en": "The rotor diameter of this wind turbine is {rotor:diameter} metres.", "fr": "Le diamètre du rotor est de {rotor:diameter} mètres." @@ -118,6 +122,7 @@ } }, { + "id": "turbine-start-date", "render": { "en": "This wind turbine went into operation on/in {start_date}.", "fr": "L’éolienne est active depuis {start_date}." diff --git a/assets/themes/parkings/parkings.json b/assets/themes/parkings/parkings.json index bb25e8bfd..ca322052c 100644 --- a/assets/themes/parkings/parkings.json +++ b/assets/themes/parkings/parkings.json @@ -22,7 +22,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 1.2, "socialImage": "", "layers": [ "parking" diff --git a/assets/themes/personal/personal.json b/assets/themes/personal/personal.json index 02e26cdbd..2896e5fbc 100644 --- a/assets/themes/personal/personal.json +++ b/assets/themes/personal/personal.json @@ -12,7 +12,7 @@ "zh_Hant": "個人化主題" }, "description": { - "en": "Create a personal theme based on all the available layers of all themes", + "en": "Create a personal theme based on all the available layers of all themes. In order to show some data, open layer selection", "nl": "Stel je eigen thema samen door lagen te combineren van alle andere themas", "es": "Crea una interficie basada en todas las capas disponibles de todas las interficies", "ca": "Crea una interfície basada en totes les capes disponibles de totes les interfícies", @@ -37,11 +37,14 @@ ], "maintainer": "MapComplete", "icon": "./assets/svg/addSmall.svg", + "clustering": { + "maxZoom": 19 + }, "version": "0", "startLat": 0, "startLon": 0, "startZoom": 16, - "widenFactor": 0.05, + "widenFactor": 1.2, "layers": [], "roamingRenderings": [] } \ No newline at end of file diff --git a/assets/themes/play_forests/play_forests.json b/assets/themes/play_forests/play_forests.json index bd824ee67..5c65a702a 100644 --- a/assets/themes/play_forests/play_forests.json +++ b/assets/themes/play_forests/play_forests.json @@ -19,7 +19,7 @@ "startLon": 0, "startZoom": 1, "hideFromOverview": true, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ "play_forest" diff --git a/assets/themes/playgrounds/playgrounds.json b/assets/themes/playgrounds/playgrounds.json index 418aa36bc..2908a88b4 100644 --- a/assets/themes/playgrounds/playgrounds.json +++ b/assets/themes/playgrounds/playgrounds.json @@ -38,7 +38,7 @@ "startLat": 50.535, "startLon": 4.399, "startZoom": 13, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "playground" diff --git a/assets/themes/shops/shops.json b/assets/themes/shops/shops.json index 09209f3f4..bae4c3cbd 100644 --- a/assets/themes/shops/shops.json +++ b/assets/themes/shops/shops.json @@ -34,7 +34,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { @@ -111,7 +111,8 @@ "render": "This shop is called {name}", "freeform": { "key": "name" - } + }, + "id": "shops-name" }, { "render": { @@ -220,7 +221,8 @@ "ja": "自動車ディーラー" } } - ] + ], + "id": "shops-shop" }, { "render": { @@ -241,7 +243,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "shops-phone" }, { "render": { @@ -262,7 +265,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "shops-website" }, { "render": { @@ -282,7 +286,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "shops-email" }, { "render": { @@ -301,7 +306,8 @@ "freeform": { "key": "opening_hours", "type": "opening_hours" - } + }, + "id": "shops-opening_hours" }, "questions", "reviews" diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 21cb17212..b0caffcc9 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -22,7 +22,7 @@ "startLat": 51.17174, "startLon": 4.449462, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 1.2, "socialImage": "./assets/themes/speelplekken/social_image.jpg", "defaultBackgroundId": "CartoDB.Positron", "layers": [ @@ -166,11 +166,13 @@ }, "tagRenderings": [ { + "id": "walk-length", "render": { "nl": "Deze wandeling is {_length:km}km lang" } }, { + "id": "walk-type", "mappings": [ { "if": "route=iwn", @@ -199,6 +201,7 @@ ] }, { + "id": "walk-description", "render": { "nl": "

Korte beschrijving:

{description}" }, @@ -209,6 +212,7 @@ } }, { + "id": "walk-operator", "question": { "nl": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" }, @@ -218,6 +222,7 @@ } }, { + "id": "walk-operator-email", "question": { "nl": "Naar wie kan men emailen bij problemen rond signalisatie?" }, @@ -257,10 +262,12 @@ "overrideAll": { "+tagRenderings": [ { + "id": "part-of-walk", "render": "Maakt deel uit van {_part_of_walking_routes}", "condition": "_part_of_walking_routes~*" }, { + "id": "has-video", "freeform": { "key": "_video:id" }, diff --git a/assets/themes/speelplekken/speelplekken_temp.json b/assets/themes/speelplekken/speelplekken_temp.json deleted file mode 100644 index 867298215..000000000 --- a/assets/themes/speelplekken/speelplekken_temp.json +++ /dev/null @@ -1,283 +0,0 @@ -{ - "id": "speelplekken_temp", - "title": { - "nl": "Speelplekken in de Antwerpse Zuidrand" - }, - "shortDescription": { - "nl": "Speelplekken in de Antwerpse Zuidrand" - }, - "description": { - "nl": "Speelplekken in de Antwerpse Zuidrand. Een project van Provincie Antwerpen, in samenwerking met Createlli, Sportpret en OpenStreetMap België" - }, - "language": [ - "nl" - ], - "maintainer": "MapComplete", - "icon": "./assets/themes/speelplekken/logo.svg", - "hideFromOverview": true, - "lockLocation": true, - "version": "0", - "startLat": 51.17174, - "startLon": 4.449462, - "startZoom": 12, - "widenFactor": 0.05, - "socialImage": "", - "defaultBackgroundId": "CartoDB.Positron", - "layers": [ - { - "builtin": "play_forest", - "override": { - "source": { - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "icon": "./assets/themes/speelplekken/speelbos.svg", - "minzoom": 12 - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - }, - { - "builtin": "playground", - "override": { - "icon": "./assets/themes/speelplekken/speeltuin.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "village_green", - "override": { - "icon": "./assets/themes/speelplekken/speelweide.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "grass_in_parks", - "override": { - "icon": "./assets/themes/speelplekken/speelweide.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "sport_pitch", - "override": { - "minzoom": 15, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "slow_roads", - "override": { - "+tagRenderings": [ - { - "question": "Is dit een publiek toegankelijk pad?", - "mappings": [ - { - "if": "access=private", - "then": "Dit is een privaat pad" - }, - { - "if": "access=no", - "then": "Dit is een privaat pad", - "hideInAnswer": true - }, - { - "if": "access=permissive", - "then": "Dit pad is duidelijk in private eigendom, maar er hangen geen verbodsborden dus mag men erover" - } - ] - } - ], - "calculatedTags": [ - "_part_of_walking_routes=Array.from(new Set(feat.memberships().map(r => \"\" + r.relation.tags.name + \"\"))).join(', ')", - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ], - "minzoom": 18, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - } - } - }, - { - "id": "walking_routes", - "name": { - "nl": "Wandelroutes van provincie Antwerpen" - }, - "description": "Walking routes by 'provincie Antwerpen'", - "source": { - "osmTags": { - "and": [ - "type=route", - "route=foot", - "operator~[pP]rovincie Antwerpen" - ] - }, - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "title": { - "render": "Wandeling {name}", - "mappings": [ - { - "if": "name~.*wandeling.*", - "then": "{name}" - } - ] - }, - "tagRenderings": [ - { - "render": { - "nl": "Deze wandeling is {_length:km}km lang" - } - }, - { - "mappings": [ - { - "if": "route=iwn", - "then": { - "nl": "Dit is een internationale wandelroute" - } - }, - { - "if": "route=nwn", - "then": { - "nl": "Dit is een nationale wandelroute" - } - }, - { - "if": "route=rwn", - "then": { - "nl": "Dit is een regionale wandelroute" - } - }, - { - "if": "route=lwn", - "then": { - "nl": "Dit is een lokale wandelroute" - } - } - ] - }, - { - "render": { - "nl": "

Korte beschrijving:

{description}" - }, - "question": "Geef een korte beschrijving van de wandeling (max 255 tekens)", - "freeform": { - "key": "description", - "type": "text" - } - }, - { - "question": { - "nl": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "render": "Signalisatie geplaatst door {operator}", - "freeform": { - "key": "operator" - } - }, - { - "question": { - "nl": "Naar wie kan men emailen bij problemen rond signalisatie?" - }, - "render": { - "nl": "Bij problemen met signalisatie kan men emailen naar {operator:email}" - }, - "freeform": { - "key": "operator:email", - "type": "email" - } - }, - "questions", - "reviews" - ], - "color": { - "render": "#6d6", - "mappings": [ - { - "if": "color~*", - "then": "{color}" - }, - { - "if": "colour~*", - "then": "{colour}" - } - ] - }, - "width": { - "render": "9" - } - } - ], - "clustering": { - "maxZoom": 16, - "minNeededElements": 100 - }, - "roamingRenderings": [ - { - "render": "Maakt deel uit van {_part_of_walking_routes}", - "condition": "_part_of_walking_routes~*" - }, - { - "render": "Een kinder-reportage vinden jullie hier", - "freeform": { - "key": "video", - "type": "url" - }, - "question": "Wat is de link naar de video-reportage?" - } - ], - "overrideAll": { - "isShown": { - "render": "yes", - "mappings": [ - { - "if": "_is_shadowed=yes", - "then": "no" - } - ] - } - } -} \ No newline at end of file diff --git a/assets/themes/sport_pitches/sport_pitches.json b/assets/themes/sport_pitches/sport_pitches.json index 7f1fdeebd..4db24cdd6 100644 --- a/assets/themes/sport_pitches/sport_pitches.json +++ b/assets/themes/sport_pitches/sport_pitches.json @@ -37,7 +37,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ "sport_pitch" diff --git a/assets/themes/surveillance/surveillance.json b/assets/themes/surveillance/surveillance.json index 001045fd1..a61633b23 100644 --- a/assets/themes/surveillance/surveillance.json +++ b/assets/themes/surveillance/surveillance.json @@ -37,7 +37,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "osm", "layers": [ diff --git a/assets/themes/toerisme_vlaanderen/license_info.json b/assets/themes/toerisme_vlaanderen/license_info.json new file mode 100644 index 000000000..374abea1e --- /dev/null +++ b/assets/themes/toerisme_vlaanderen/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "logo.png", + "license": "Logo (all rights reserved)", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://www.toerismevlaanderen.be/" + ] + } +] \ No newline at end of file diff --git a/assets/themes/toerisme_vlaanderen/logo.png b/assets/themes/toerisme_vlaanderen/logo.png new file mode 100644 index 000000000..6d0d16dd8 Binary files /dev/null and b/assets/themes/toerisme_vlaanderen/logo.png differ diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index be5567d5d..2b303ea14 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -14,13 +14,13 @@ "nl": "Een kaart om toeristisch relevante info op aan te duiden" }, "description": { - "nl": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen" + "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen" }, "icon": "./assets/svg/star.svg", "startZoom": 8, "startLat": 50.8536, "startLon": 4.433, - "widenFactor": 0.2, + "widenFactor": 1.5, "layers": [ { "builtin": [ diff --git a/assets/themes/toilets/toilets.json b/assets/themes/toilets/toilets.json index e343d9ea2..1d1567de4 100644 --- a/assets/themes/toilets/toilets.json +++ b/assets/themes/toilets/toilets.json @@ -35,7 +35,7 @@ "startZoom": 12, "startLat": 51.2095, "startLon": 3.2222, - "widenFactor": 0.05, + "widenFactor": 3, "icon": "./assets/themes/toilets/toilets.svg", "layers": [ "toilet" diff --git a/assets/themes/trees/trees.json b/assets/themes/trees/trees.json index ea26fdeca..c609a43f1 100644 --- a/assets/themes/trees/trees.json +++ b/assets/themes/trees/trees.json @@ -45,10 +45,11 @@ "startLat": 50.642, "startLon": 4.482, "startZoom": 8, - "widenFactor": 0.01, + "widenFactor": 1.01, "socialImage": "./assets/themes/trees/logo.svg", "clustering": { - "maxZoom": 18 + "maxZoom": 19, + "minNeededElements": 25 }, "layers": [ "tree_node" diff --git a/assets/themes/uk_addresses/housenumber_unknown_small.svg b/assets/themes/uk_addresses/housenumber_unknown_small.svg new file mode 100644 index 000000000..398ce8f72 --- /dev/null +++ b/assets/themes/uk_addresses/housenumber_unknown_small.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/assets/themes/uk_addresses/license_info.json b/assets/themes/uk_addresses/license_info.json index 0c6fb0715..7d805cee4 100644 --- a/assets/themes/uk_addresses/license_info.json +++ b/assets/themes/uk_addresses/license_info.json @@ -39,5 +39,13 @@ "https://github.com/streetcomplete/StreetComplete/tree/master/res/graphics", "https://f-droid.org/packages/de.westnordost.streetcomplete/" ] + }, + { + "path": "housenumber_unknown_small.svg", + "license": "CC0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] } ] \ No newline at end of file diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 654bb2177..8dd07bf47 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -15,11 +15,15 @@ "maintainer": "Pieter Vander Vennet, Rob Nickerson, Russ Garrett", "icon": "./assets/themes/uk_addresses/housenumber_unknown.svg", "version": "2021-09-17", - "startLat": -0.08528530407, - "startLon": 51.52103754846, - "startZoom": 18, - "widenFactor": 0.5, + "startLat": -0.08706, + "startLon": 51.52224, + "startZoom": 17, + "widenFactor": 1.01, "socialImage": "", + "clustering": { + "minNeededFeatures": 25, + "maxZoom": 17 + }, "layers": [ { "id": "to_import", @@ -34,33 +38,36 @@ "minzoom": 12, "wayHandling": 1, "icon": { - "render": "./assets/themes/uk_addresses/housenumber_unknown.svg" - }, - "iconSize": { - "render": "40,40,center", + "render": "./assets/themes/uk_addresses/housenumber_unknown.svg", "mappings": [ { "if": "_embedding_object:id~*", - "then": "15,15,center" + "then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg" }, { "if": "_imported=yes", - "then": "8,8,center" + "then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg" } ] }, + "iconSize": { + "render": "40,40,center" + }, "title": { "render": "Address to be determined" }, "tagRenderings": [ { + "id": "uk_addresses_explanation", "render": "There probably is an address here" }, { + "id": "uk_addresses_embedding_outline", "render": "An outline embedding this point with an address already exists in OpenStreetMap.
This
object has address {_embedding_object:addr:street} {_embedding_object:addr:housenumber}", "condition": "_embedding_object:id~*" }, { + "id": "uk_addresses_import_button", "render": "{import_button(ref:inspireid=$inspireid, Add this address, ./assets/themes/uk_addresses/housenumber_add.svg)}" }, "all_tags" @@ -70,6 +77,22 @@ "_embedding_object:addr:housenumber=JSON.parse(feat.properties._embedding_object)?.['addr:housenumber']", "_embedding_object:addr:street=JSON.parse(feat.properties._embedding_object)?.['addr:street']", "_embedding_object:id=JSON.parse(feat.properties._embedding_object)?.id" + ], + "filter": [ + { + "id": "to_handle", + "options": [ + { + "question": "Only show non-matched objects", + "osmTags": { + "and": [ + "_imported=", + "_embedding_object:id=" + ] + } + } + ] + } ] }, { @@ -109,11 +132,13 @@ }, "tagRenderings": [ { + "id": "uk_addresses_explanation_osm", "render": { "en": "This address is saved in OpenStreetMap" } }, { + "id": "uk_addresses_housenumber", "render": { "en": "The housenumber is {addr:housenumber}" }, @@ -137,6 +162,7 @@ ] }, { + "id": "uk_addresses_street", "render": { "en": "This address is in street {addr:street}" }, @@ -149,17 +175,17 @@ "mappings": [ { "if": "addr:street:={_closest_street:0:name}", - "then": "{_closest_street:0:name} {_closest_street:0:distance}m", + "then": "Located in {_closest_street:0:name} (~{_closest_street:0:distance}m away)", "hideInAnswer": "_closest_street:0:name=" }, { "if": "addr:street:={_closest_street:1:name}", - "then": "{_closest_street:1:name} {_closest_street:1:distance}m", + "then": "Located in {_closest_street:1:name} (~{_closest_street:1:distance}m away)", "hideInAnswer": "_closest_street:1:name=" }, { "if": "addr:street:={_closest_street:2:name}", - "then": "{_closest_street:2:name} {_closest_street:2:distance}m", + "then": "Located in {_closest_street:2:name} (~{_closest_street:2:distance}m away)", "hideInAnswer": "_closest_street:2:name=" } ], @@ -213,8 +239,7 @@ "then": "#ff0" } ] - }, - "presets": [] + } }, { "id": "named_streets", diff --git a/assets/themes/waste_basket/waste_basket.json b/assets/themes/waste_basket/waste_basket.json index 2a1ecef84..eb95d85eb 100644 --- a/assets/themes/waste_basket/waste_basket.json +++ b/assets/themes/waste_basket/waste_basket.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ { diff --git a/assets/themes/widths/icon.svg b/assets/themes/widths/icon.svg deleted file mode 100644 index 6a0bda749..000000000 --- a/assets/themes/widths/icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/assets/themes/widths/license_info.json b/assets/themes/widths/license_info.json deleted file mode 100644 index 20cd90555..000000000 --- a/assets/themes/widths/license_info.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "path": "icon.svg", - "license": "CC0; trivial", - "authors": [], - "sources": [] - } -] \ No newline at end of file diff --git a/assets/themes/widths/width.json b/assets/themes/widths/width.json deleted file mode 100644 index 5ee75eb7e..000000000 --- a/assets/themes/widths/width.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "id": "width", - "title": { - "nl": "Straatbreedtes" - }, - "shortDescription": { - "nl": "Is de straat breed genoeg?" - }, - "description": { - "nl": "

De straat is opgebruikt

\n

Er is steeds meer druk op de openbare ruimte. Voetgangers, fietsers, steps, auto's, bussen, bestelwagens, buggies, cargobikes, ... willen allemaal hun deel van de openbare ruimte.

\n

In deze studie nemen we Brugge onder de loep en kijken we hoe breed elke straat is én hoe breed elke straat zou moeten zijn voor een veilig én vlot verkeer.

\n

Legende

\n     Straat te smal voor veilig verkeer
\n     Straat is breed genoeg veilig verkeer
\n     Straat zonder voetpad, te smal als ook voetgangers plaats krijgen
\n     Woonerf, autoluw, autoloos of enkel plaatselijk verkeer
\n
\n
\n Een gestippelde lijn is een straat waar ook voor fietsers éénrichtingsverkeer geldt.
\n Klik op een straat om meer informatie te zien.\n

Hoe gaan we verder?

\n Verschillende ingrepen kunnen de stad teruggeven aan de inwoners en de stad leefbaarder en levendiger maken.
\n Denk aan:\n
    \n
  • De autovrije zone's uitbreiden
  • \n
  • De binnenstad fietszone maken
  • \n
  • Het aantal woonerven uitbreiden
  • \n
  • Grotere auto's meer belasten - ze nemen immers meer parkeerruimte in.
  • \n
  • Laat toeristen verplicht parkeren onder het zand; een (fiets)taxi kan hen naar hun hotel brengen
  • \n
  • Voorzie in elke straat enkele parkeerplaatsen voor kortparkeren. Zo kunnen leveringen, iemand afzetten,... gebeuren zonder op het voetpad en fietspad te parkeren
  • \n
" - }, - "language": [ - "nl" - ], - "hideFromOverview": true, - "enableUserBadge": false, - "enableShareScreen": false, - "enableMoreQuests": false, - "enableLayers": false, - "enableSearch": false, - "enableGeolocation": false, - "maintainer": "", - "icon": "./assets/themes/widths/icon.svg", - "version": "0", - "startLat": 51.20875, - "startLon": 3.22435, - "startZoom": 14, - "widenFactor": 0.05, - "socialImage": "", - "layers": [ - { - "id": "widths", - "name": { - "nl": "Straten met een breedte" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "width:carriageway~*" - ] - } - }, - "titleIcons": [], - "title": { - "render": { - "nl": "{name}" - }, - "condition": { - "and": [] - }, - "mappings": [ - { - "if": { - "and": [ - "name=" - ] - }, - "then": { - "nl": "Naamloos segmet" - } - } - ] - }, - "tagRenderings": [ - { - "render": "Deze straat is {width:carriageway}m breed", - "question": "Hoe breed is deze straat?", - "freeform": { - "key": "width:carriageway", - "type": "length", - "helperArgs": [ - 21, - "map" - ] - } - }, - { - "render": "Deze straat heeft {_width:difference}m te weinig:", - "mappings": [ - { - "if": { - "or": [ - "_width:difference~-.*", - "_width:difference=0.0" - ] - }, - "then": "Deze straat is breed genoeg:" - } - ] - }, - { - "render": "{_width:needed:cars}m voor het autoverkeer", - "mappings": [ - { - "if": "oneway=yes", - "then": "{_width:needed:cars}m voor het éénrichtings-autoverkeer" - }, - { - "if": "oneway=no", - "then": "{_width:needed:cars}m voor het tweerichtings-autoverkeer" - } - ] - }, - { - "render": "{_width:needed:parking}m voor het geparkeerde wagens", - "condition": "_width:needed:parking!=0.0" - }, - { - "render": "{_width:needed:cyclists}m voor fietsers", - "mappings": [ - { - "if": "bicycle=use_sidepath", - "then": "Fietsers hebben hier een vrijliggend fietspad en worden dus niet meegerekend" - }, - { - "if": "oneway:bicycle=yes", - "then": "{_width:needed:cyclists}m voor fietsers, die met de rijrichting mee moeten" - } - ] - }, - { - "render": "{_width:needed:pedestrians}m voor voetgangers", - "condition": "_width:needed:pedestrians!=0.0", - "mappings": [ - { - "if": { - "or": [ - "sidewalk=none", - "sidewalk=no" - ] - }, - "then": "{_width:needed:pedestrians}m voor voetgangers: er zijn hier geen voetpaden" - }, - { - "if": { - "or": [ - "sidewalk=left", - "sidewalk=right" - ] - }, - "then": "{_width:needed:pedestrians}m voor voetgangers: er is slechts aan één kant een voetpad" - } - ] - }, - { - "render": "{_width:needed}m nodig in het totaal" - } - ], - "icon": { - "render": "./assets/themes/widths/icon.svg" - }, - "width": { - "render": "4" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f", - "mappings": [ - { - "if": { - "or": [ - "access=destination", - "highway=living_street", - "highway=pedestrian", - "motor_vehicle=no", - "motor_vehicle=destination" - ] - }, - "then": "lightgrey" - }, - { - "if": "_width:difference~-.*", - "then": "#0f0" - }, - { - "if": { - "and": [ - "_width:difference!~-.*", - "_width:difference:no_pedestrians~-.*" - ] - }, - "then": "orange" - }, - { - "if": "_width:difference!~-.*", - "then": "#f00" - } - ] - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": { - "and": [ - "oneway=yes", - { - "or": [ - "oneway:bicycle=yes", - "oneway:bicycle=" - ] - } - ] - }, - "then": "5 6" - } - ] - }, - "presets": [] - } - ], - "roamingRenderings": [], - "defaultBackgroundId": "Stadia.AlidadeSmoothDark" -} \ No newline at end of file diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index a4f297283..4cbe196ae 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1331,6 +1331,11 @@ video { background-color: rgba(156, 163, 175, var(--tw-bg-opacity)); } +.bg-indigo-100 { + --tw-bg-opacity: 1; + background-color: rgba(224, 231, 255, var(--tw-bg-opacity)); +} + .bg-gray-300 { --tw-bg-opacity: 1; background-color: rgba(209, 213, 219, var(--tw-bg-opacity)); @@ -1346,11 +1351,6 @@ video { background-color: rgba(229, 231, 235, var(--tw-bg-opacity)); } -.bg-indigo-100 { - --tw-bg-opacity: 1; - background-color: rgba(224, 231, 255, var(--tw-bg-opacity)); -} - .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgba(243, 244, 246, var(--tw-bg-opacity)); @@ -1582,10 +1582,6 @@ video { text-decoration: underline; } -.line-through { - text-decoration: line-through; -} - .opacity-0 { opacity: 0; } @@ -2001,6 +1997,8 @@ li::marker { } @-webkit-keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ + from { transform: translateX(0%); } @@ -2011,6 +2009,8 @@ li::marker { } @keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ + from { transform: translateX(0%); } @@ -2020,6 +2020,90 @@ li::marker { } } +.hand-drag-animation { + -webkit-animation: hand-drag-animation 6s ease-in-out infinite; + animation: hand-drag-animation 6s ease-in-out infinite; + transform-origin: 50% 125%; +} + +@-webkit-keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } +} + +@keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } +} + /**************************************/ #topleft-tools { diff --git a/index.css b/index.css index bb063beec..4361e9503 100644 --- a/index.css +++ b/index.css @@ -303,6 +303,7 @@ li::marker { @keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ from { transform: translateX(0%); } @@ -312,6 +313,51 @@ li::marker { } } +.hand-drag-animation { + animation: hand-drag-animation 6s ease-in-out infinite; + transform-origin: 50% 125%; +} + +@keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } + +} + /**************************************/ diff --git a/langs/en.json b/langs/en.json index fdfc46fe5..9687f11a9 100644 --- a/langs/en.json +++ b/langs/en.json @@ -13,7 +13,8 @@ "uploadDone": "Your picture has been added. Thanks for helping out!", "dontDelete": "Cancel", "doDelete": "Remove image", - "isDeleted": "Deleted" + "isDeleted": "Deleted", + "hasBeenImported": "This feature has been imported" }, "centerMessage": { "loadingData": "Loading data…", diff --git a/langs/layers/ca.json b/langs/layers/ca.json index 270daa003..1c12a8ed7 100644 --- a/langs/layers/ca.json +++ b/langs/layers/ca.json @@ -7,18 +7,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Aquest desfibril·lador està a l'interior" - }, - "1": { - "then": "Aquest desfibril·lador està a l'exterior" - } - }, - "question": "Està el desfibril·lador a l'interior?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Accés lliure" @@ -36,18 +25,29 @@ "question": "Està el desfibril·lador accessible lliurement?", "render": "L'accés és {access}" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-defibrillator:location:en": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Aquest desfibril·lador està a l'interior" + }, + "1": { + "then": "Aquest desfibril·lador està a l'exterior" + } + }, + "question": "Està el desfibril·lador a l'interior?" + }, + "defibrillator-level": { "question": "A quina planta està el desfibril·lador localitzat?", "render": "Aquest desfibril·lador és a la planta {level}" - }, - "5": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" - }, - "6": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" - }, - "7": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" } }, "title": { @@ -56,27 +56,27 @@ }, "ghost_bike": { "tagRenderings": { - "4": { + "ghost_bike-inscription": { "render": "{inscription}" } } }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } }, "playground": { "tagRenderings": { - "7": { + "playground-email": { "render": "{email}" }, - "8": { + "playground-phone": { "render": "{phone}" } } diff --git a/langs/layers/de.json b/langs/layers/de.json index 0f91d9343..b95c28ac5 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -3,12 +3,11 @@ "name": "Sitzbänke", "presets": { "0": { - "description": "Neue Sitzbank eintragen", - "title": "Sitzbank" + "title": "sitzbank" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Rückenlehne: Ja" @@ -20,39 +19,7 @@ "question": "Hat diese Bank eine Rückenlehne?", "render": "Rückenlehne" }, - "2": { - "question": "Wie viele Sitzplätze hat diese Bank?", - "render": "{seats} Sitzplätze" - }, - "3": { - "mappings": { - "0": { - "then": "Material: Holz" - }, - "1": { - "then": "Material: Metall" - }, - "2": { - "then": "Material: Stein" - }, - "3": { - "then": "Material: Beton" - }, - "4": { - "then": "Material: Kunststoff" - }, - "5": { - "then": "Material: Stahl" - } - }, - "question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", - "render": "Material: {material}" - }, - "4": { - "question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", - "render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Farbe: braun" @@ -82,7 +49,39 @@ "question": "Welche Farbe hat diese Sitzbank?", "render": "Farbe: {colour}" }, - "6": { + "bench-direction": { + "question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", + "render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: Holz" + }, + "1": { + "then": "Material: Metall" + }, + "2": { + "then": "Material: Stein" + }, + "3": { + "then": "Material: Beton" + }, + "4": { + "then": "Material: Kunststoff" + }, + "5": { + "then": "Material: Stahl" + } + }, + "question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "Wie viele Sitzplätze hat diese Bank?", + "render": "{seats} Sitzplätze" + }, + "bench-survey:date": { "question": "Wann wurde diese Bank zuletzt überprüft?", "render": "Diese Bank wurde zuletzt überprüft am {survey:date}" } @@ -94,11 +93,11 @@ "bench_at_pt": { "name": "Sitzbänke bei Haltestellen", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Stehbank" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -116,19 +115,7 @@ "bicycle_library": { "description": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", "tagRenderings": { - "6": { - "mappings": { - "0": { - "then": "Das Ausleihen eines Fahrrads ist kostenlos" - }, - "1": { - "then": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr" - } - }, - "question": "Wie viel kostet das Ausleihen eines Fahrrads?", - "render": "Das Ausleihen eines Fahrrads kostet {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Fahrräder für Kinder verfügbar" @@ -141,6 +128,18 @@ } }, "question": "Wer kann hier Fahrräder ausleihen?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Das Ausleihen eines Fahrrads ist kostenlos" + }, + "1": { + "then": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr" + } + }, + "question": "Wie viel kostet das Ausleihen eines Fahrrads?", + "render": "Das Ausleihen eines Fahrrads kostet {charge}" } } }, @@ -152,7 +151,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Dieser Automat funktioniert" @@ -180,11 +179,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wie heißt dieses Fahrrad-Café?", - "render": "Dieses Fahrrad-Café heißt {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann" @@ -195,18 +190,17 @@ }, "question": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?" }, - "3": { - "mappings": { - "0": { - "then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an" - }, - "1": { - "then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an" - } - }, - "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" + "bike_cafe-email": { + "question": "Wie lautet die E-Mail-Adresse von {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Wie heißt dieses Fahrrad-Café?", + "render": "Dieses Fahrrad-Café heißt {name}" + }, + "bike_cafe-phone": { + "question": "Wie lautet die Telefonnummer von {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Dieses Fahrrad-Café repariert Fahrräder" @@ -217,14 +211,19 @@ }, "question": "Repariert dieses Fahrrad-Café Fahrräder?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an" + }, + "1": { + "then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an" + } + }, + "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" + }, + "bike_cafe-website": { "question": "Was ist die Webseite von {name}?" - }, - "6": { - "question": "Wie lautet die Telefonnummer von {name}?" - }, - "7": { - "question": "Wie lautet die E-Mail-Adresse von {name}?" } }, "title": { @@ -252,19 +251,6 @@ "render": "Fahrrad-Reinigungsdienst" } }, - "bike_monitoring_station": { - "title": { - "mappings": { - "0": { - "then": "Fahrradzählstation {name}" - }, - "1": { - "then": "Fahrradzählstation {ref}" - } - }, - "render": "Fahrradzählstation" - } - }, "bike_parking": { "name": "Fahrrad-Parkplätze", "presets": { @@ -273,7 +259,16 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Öffentlich zugänglich" + } + }, + "question": "Wer kann diesen Fahrradparplatz nutzen?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Fahrradbügel " @@ -303,7 +298,40 @@ "question": "Was ist die Art dieses Fahrrad-Parkplatzes?", "render": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", + "render": "Platz für {capacity} Fahrräder" + }, + "Cargo bike capacity?": { + "question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", + "render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Dieser Parkplatz bietet Platz für Lastenfahrräder" + }, + "1": { + "then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder." + }, + "2": { + "then": "Es ist nicht erlaubt, Lastenfahrräder zu parken" + } + }, + "question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Dieser Parkplatz ist überdacht (er hat ein Dach)" + }, + "1": { + "then": "Dieser Parkplatz ist nicht überdacht" + } + }, + "question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze." + }, + "Underground?": { "mappings": { "0": { "then": "Tiefgarage" @@ -318,48 +346,6 @@ "then": "Ebenerdiges Parken" } } - }, - "3": { - "mappings": { - "0": { - "then": "Dieser Parkplatz ist überdacht (er hat ein Dach)" - }, - "1": { - "then": "Dieser Parkplatz ist nicht überdacht" - } - }, - "question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze." - }, - "4": { - "question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", - "render": "Platz für {capacity} Fahrräder" - }, - "5": { - "mappings": { - "0": { - "then": "Öffentlich zugänglich" - } - }, - "question": "Wer kann diesen Fahrradparplatz nutzen?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Dieser Parkplatz bietet Platz für Lastenfahrräder" - }, - "1": { - "then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder." - }, - "2": { - "then": "Es ist nicht erlaubt, Lastenfahrräder zu parken" - } - }, - "question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?" - }, - "7": { - "question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", - "render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder" } }, "title": { @@ -382,7 +368,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "Die Fahrradpumpe ist kaputt" + }, + "1": { + "then": "Die Fahrradpumpe ist betriebsbereit" + } + }, + "question": "Ist die Fahrradpumpe noch funktionstüchtig?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Es ist nur eine Pumpe vorhanden" @@ -396,22 +393,7 @@ }, "question": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?" }, - "2": { - "question": "Wer wartet diese Fahrradpumpe?", - "render": "Gewartet von {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Immer geöffnet" - }, - "1": { - "then": "Immer geöffnet" - } - }, - "question": "Wann ist diese Fahrradreparaturstelle geöffnet?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Es gibt ein Kettenwerkzeug" @@ -422,7 +404,7 @@ }, "question": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Es gibt einen Haken oder Ständer" @@ -433,18 +415,47 @@ }, "question": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "Die Fahrradpumpe ist kaputt" + "then": "Manuelle Pumpe" }, "1": { - "then": "Die Fahrradpumpe ist betriebsbereit" + "then": "Elektrische Pumpe" } }, - "question": "Ist die Fahrradpumpe noch funktionstüchtig?" + "question": "Ist dies eine elektrische Fahrradpumpe?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Es gibt ein Manometer" + }, + "1": { + "then": "Es gibt kein Manometer" + }, + "2": { + "then": "Es gibt ein Manometer, aber es ist kaputt" + } + }, + "question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Immer geöffnet" + }, + "1": { + "then": "Immer geöffnet" + } + }, + "question": "Wann ist diese Fahrradreparaturstelle geöffnet?" + }, + "bike_repair_station-operator": { + "question": "Wer wartet diese Fahrradpumpe?", + "render": "Gewartet von {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sklaverand (auch bekannt als Presta)" @@ -458,31 +469,6 @@ }, "question": "Welche Ventile werden unterstützt?", "render": "Diese Pumpe unterstützt die folgenden Ventile: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manuelle Pumpe" - }, - "1": { - "then": "Elektrische Pumpe" - } - }, - "question": "Ist dies eine elektrische Fahrradpumpe?" - }, - "12": { - "mappings": { - "0": { - "then": "Es gibt ein Manometer" - }, - "1": { - "then": "Es gibt kein Manometer" - }, - "2": { - "then": "Es gibt ein Manometer, aber es ist kaputt" - } - }, - "question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?" } }, "title": { @@ -514,31 +500,43 @@ } }, "tagRenderings": { - "2": { - "question": "Wie heißt dieser Fahrradladen?", - "render": "Dieses Fahrradgeschäft heißt {name}" - }, - "3": { - "question": "Was ist die Webseite von {name}?" - }, - "4": { - "question": "Wie lautet die Telefonnummer von {name}?" - }, - "5": { - "question": "Wie lautet die E-Mail-Adresse von {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Dieses Geschäft verkauft Fahrräder" + "then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an" }, "1": { - "then": "Dieses Geschäft verkauft keine Fahrräder" + "then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" } }, - "question": "Verkauft dieser Laden Fahrräder?" + "question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Dieses Geschäft reinigt Fahrräder" + }, + "1": { + "then": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" + }, + "2": { + "then": "Dieser Laden bietet keine Fahrradreinigung an" + } + }, + "question": "Werden hier Fahrräder gewaschen?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Dieses Geschäft vermietet Fahrräder" + }, + "1": { + "then": "Dieses Geschäft vermietet keine Fahrräder" + } + }, + "question": "Vermietet dieser Laden Fahrräder?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Dieses Geschäft repariert Fahrräder" @@ -555,18 +553,7 @@ }, "question": "Repariert dieses Geschäft Fahrräder?" }, - "11": { - "mappings": { - "0": { - "then": "Dieses Geschäft vermietet Fahrräder" - }, - "1": { - "then": "Dieses Geschäft vermietet keine Fahrräder" - } - }, - "question": "Vermietet dieser Laden Fahrräder?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Dieses Geschäft verkauft gebrauchte Fahrräder" @@ -580,18 +567,18 @@ }, "question": "Verkauft dieses Geschäft gebrauchte Fahrräder?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an" + "then": "Dieses Geschäft verkauft Fahrräder" }, "1": { - "then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" + "then": "Dieses Geschäft verkauft keine Fahrräder" } }, - "question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" + "question": "Verkauft dieser Laden Fahrräder?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an" @@ -605,19 +592,18 @@ }, "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" }, - "15": { - "mappings": { - "0": { - "then": "Dieses Geschäft reinigt Fahrräder" - }, - "1": { - "then": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" - }, - "2": { - "then": "Dieser Laden bietet keine Fahrradreinigung an" - } - }, - "question": "Werden hier Fahrräder gewaschen?" + "bike_shop-email": { + "question": "Wie lautet die E-Mail-Adresse von {name}?" + }, + "bike_shop-name": { + "question": "Wie heißt dieser Fahrradladen?", + "render": "Dieses Fahrradgeschäft heißt {name}" + }, + "bike_shop-phone": { + "question": "Wie lautet die Telefonnummer von {name}?" + }, + "bike_shop-website": { + "question": "Was ist die Webseite von {name}?" } }, "title": { @@ -660,18 +646,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Dieser Defibrillator befindet sich im Gebäude" - }, - "1": { - "then": "Dieser Defibrillator befindet sich im Freien" - } - }, - "question": "Befindet sich dieser Defibrillator im Gebäude?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Öffentlich zugänglich" @@ -689,7 +664,7 @@ "question": "Ist dieser Defibrillator frei zugänglich?", "render": "Zugang ist {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" @@ -697,7 +672,42 @@ }, "render": "Es gibt keine Informationen über den Gerätetyp" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", + "render": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", + "render": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", + "render": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" + }, + "defibrillator-description": { + "question": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)", + "render": "Zusätzliche Informationen: {description}" + }, + "defibrillator-email": { + "question": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?", + "render": "E-Mail für Fragen zu diesem Defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)", + "render": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Dieser Defibrillator befindet sich im Gebäude" + }, + "1": { + "then": "Dieser Defibrillator befindet sich im Freien" + } + }, + "question": "Befindet sich dieser Defibrillator im Gebäude?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Dieser Defibrillator befindet sich im Erdgeschoss" @@ -709,31 +719,7 @@ "question": "In welchem Stockwerk befindet sich dieser Defibrillator?", "render": "Dieser Defibrallator befindet sich im {level}. Stockwerk" }, - "5": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", - "render": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" - }, - "6": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", - "render": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" - }, - "7": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", - "render": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" - }, - "9": { - "question": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)", - "render": "Offizielle Identifikationsnummer des Geräts: {ref}" - }, - "10": { - "question": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?", - "render": "E-Mail für Fragen zu diesem Defibrillator: {email}" - }, - "11": { - "question": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?", - "render": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 geöffnet (auch an Feiertagen)" @@ -741,11 +727,15 @@ }, "question": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" }, - "13": { - "question": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)", - "render": "Zusätzliche Informationen: {description}" + "defibrillator-phone": { + "question": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?", + "render": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)", + "render": "Offizielle Identifikationsnummer des Geräts: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Heute überprüft!" @@ -753,10 +743,6 @@ }, "question": "Wann wurde dieser Defibrillator zuletzt überprüft?", "render": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" - }, - "15": { - "question": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)", - "render": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}" } }, "title": { @@ -767,15 +753,11 @@ "name": "Trinkwasser", "presets": { "0": { - "title": "Trinkwasser" + "title": "trinkwasser" } }, "tagRenderings": { - "1": { - "question": "Ist diese Trinkwasserstelle noch in Betrieb?", - "render": "Der Betriebsstatus ist {operational_status" - }, - "2": { + "Bottle refill": { "mappings": { "0": { "then": "Es ist einfach, Wasserflaschen nachzufüllen" @@ -786,7 +768,11 @@ }, "question": "Wie einfach ist es, Wasserflaschen zu füllen?" }, - "3": { + "Still in use?": { + "question": "Ist diese Trinkwasserstelle noch in Betrieb?", + "render": "Der Betriebsstatus ist {operational_status" + }, + "render-closest-drinking-water": { "render": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter" } }, @@ -802,10 +788,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird." }, - "2": { + "ghost_bike-inscription": { + "question": "Wie lautet die Inschrift auf diesem Geisterrad?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Auf dem Fahrrad ist kein Name angegeben" @@ -814,13 +804,9 @@ "question": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", "render": "Im Gedenken an {name}" }, - "3": { + "ghost_bike-source": { "question": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", "render": "Mehr Informationen" - }, - "4": { - "question": "Wie lautet die Inschrift auf diesem Geisterrad?", - "render": "{inscription}" } }, "title": { @@ -836,7 +822,7 @@ "name": "Informationstafeln", "presets": { "0": { - "title": "Informationstafel" + "title": "informationstafel" } }, "title": { @@ -852,16 +838,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Diese Karte basiert auf OpenStreetMap" - } - }, - "question": "Auf welchen Daten basiert diese Karte?", - "render": "Diese Karte basiert auf {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz" @@ -880,6 +857,15 @@ } }, "question": "Ist die OpenStreetMap-Attribution vorhanden?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Diese Karte basiert auf OpenStreetMap" + } + }, + "question": "Auf welchen Daten basiert diese Karte?", + "render": "Diese Karte basiert auf {map_source}" } }, "title": { @@ -888,7 +874,7 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Dogs?": { "mappings": { "0": { "then": "Hunde müssen angeleint sein" @@ -902,13 +888,13 @@ }, "question": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" }, - "6": { - "question": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" - }, - "8": { + "Email": { "render": "{email}" }, - "9": { + "Website": { + "question": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" + }, + "phone": { "render": "{phone}" } } @@ -917,11 +903,11 @@ "name": "Picknick-Tische", "presets": { "0": { - "title": "Picknicktisch" + "title": "picknicktisch" } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Dies ist ein Picknicktisch aus Holz" @@ -942,7 +928,63 @@ "description": "Spielplätze", "name": "Spielplätze", "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Vollständig zugänglich für Rollstuhlfahrer" + }, + "1": { + "then": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer" + }, + "2": { + "then": "Nicht zugänglich für Rollstuhlfahrer" + } + }, + "question": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Zugänglich für die Allgemeinheit" + }, + "1": { + "then": "Zugänglich für die Allgemeinheit" + }, + "2": { + "then": "Nur für Kunden des Betreibers zugänglich" + }, + "3": { + "then": "Nur für Schüler der Schule zugänglich" + }, + "4": { + "then": "Nicht zugänglich" + } + }, + "question": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?" + }, + "playground-email": { + "question": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Dieser Spielplatz ist nachts beleuchtet" + }, + "1": { + "then": "Dieser Spielplatz ist nachts nicht beleuchtet" + } + }, + "question": "Ist dieser Spielplatz nachts beleuchtet?" + }, + "playground-operator": { + "question": "Wer betreibt diesen Spielplatz?", + "render": "Betrieben von {operator}" + }, + "playground-phone": { + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "Die Oberfläche ist Gras" @@ -971,62 +1013,6 @@ }, "question": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", "render": "Die Oberfläche ist {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Dieser Spielplatz ist nachts beleuchtet" - }, - "1": { - "then": "Dieser Spielplatz ist nachts nicht beleuchtet" - } - }, - "question": "Ist dieser Spielplatz nachts beleuchtet?" - }, - "5": { - "question": "Wer betreibt diesen Spielplatz?", - "render": "Betrieben von {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Zugänglich für die Allgemeinheit" - }, - "1": { - "then": "Zugänglich für die Allgemeinheit" - }, - "2": { - "then": "Nur für Kunden des Betreibers zugänglich" - }, - "3": { - "then": "Nur für Schüler der Schule zugänglich" - }, - "4": { - "then": "Nicht zugänglich" - } - }, - "question": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?" - }, - "7": { - "question": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?", - "render": "{email}" - }, - "8": { - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Vollständig zugänglich für Rollstuhlfahrer" - }, - "1": { - "then": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer" - }, - "2": { - "then": "Nicht zugänglich für Rollstuhlfahrer" - } - }, - "question": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?" } }, "title": { @@ -1047,20 +1033,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Dieser Bücherschrank hat keinen Namen" - } - }, - "question": "Wie heißt dieser öffentliche Bücherschrank?", - "render": "Der Name dieses Bücherschrank lautet {name}" - }, - "3": { - "question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", - "render": "{capacity} Bücher passen in diesen Bücherschrank" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Vorwiegend Kinderbücher" @@ -1074,7 +1047,18 @@ }, "question": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Öffentlich zugänglich" + }, + "1": { + "then": "Nur für Kunden zugänglich" + } + }, + "question": "Ist dieser öffentliche Bücherschrank frei zugänglich?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Dieser Bücherschrank befindet sich im Innenbereich" @@ -1088,22 +1072,7 @@ }, "question": "Befindet sich dieser Bücherschrank im Freien?" }, - "6": { - "mappings": { - "0": { - "then": "Öffentlich zugänglich" - }, - "1": { - "then": "Nur für Kunden zugänglich" - } - }, - "question": "Ist dieser öffentliche Bücherschrank frei zugänglich?" - }, - "7": { - "question": "Wer unterhält diesen öffentlichen Bücherschrank?", - "render": "Betrieben von {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Teil des Netzwerks 'Little Free Library'" @@ -1115,7 +1084,24 @@ "question": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", "render": "Dieser Bücherschrank ist Teil von {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", + "render": "{capacity} Bücher passen in diesen Bücherschrank" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Dieser Bücherschrank hat keinen Namen" + } + }, + "question": "Wie heißt dieser öffentliche Bücherschrank?", + "render": "Der Name dieses Bücherschrank lautet {name}" + }, + "public_bookcase-operator": { + "question": "Wer unterhält diesen öffentlichen Bücherschrank?", + "render": "Betrieben von {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks" @@ -1124,11 +1110,11 @@ "question": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", "render": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Wann wurde dieser öffentliche Bücherschrank installiert?", "render": "Installiert am {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", "render": "Weitere Informationen auf der Webseite" } @@ -1147,15 +1133,15 @@ "presets": { "0": { "description": "Eine öffentlich zugängliche Toilette", - "title": "Toilette" + "title": "toilette" }, "1": { "description": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", - "title": "Toiletten mit rollstuhlgerechter Toilette" + "title": "toiletten mit rollstuhlgerechter Toilette" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Öffentlicher Zugang" @@ -1176,61 +1162,7 @@ "question": "Sind diese Toiletten öffentlich zugänglich?", "render": "Zugang ist {access}" }, - "2": { - "mappings": { - "0": { - "then": "Dies sind bezahlte Toiletten" - }, - "1": { - "then": "Kostenlose Nutzung" - } - }, - "question": "Können diese Toiletten kostenlos benutzt werden?" - }, - "3": { - "question": "Wie viel muss man für diese Toiletten bezahlen?", - "render": "Die Gebühr beträgt {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Es gibt eine Toilette für Rollstuhlfahrer" - }, - "1": { - "then": "Kein Zugang für Rollstuhlfahrer" - } - }, - "question": "Gibt es eine Toilette für Rollstuhlfahrer?" - }, - "5": { - "mappings": { - "0": { - "then": "Es gibt nur Sitztoiletten" - }, - "1": { - "then": "Hier gibt es nur Pissoirs" - }, - "2": { - "then": "Es gibt hier nur Hocktoiletten" - }, - "3": { - "then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar" - } - }, - "question": "Welche Art von Toiletten sind das?" - }, - "6": { - "mappings": { - "0": { - "then": "Ein Wickeltisch ist verfügbar" - }, - "1": { - "then": "Es ist kein Wickeltisch verfügbar" - } - }, - "question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "Der Wickeltisch befindet sich in der Damentoilette. " @@ -1247,6 +1179,60 @@ }, "question": "Wo befindet sich der Wickeltisch?", "render": "Die Wickeltabelle befindet sich in {changing_table:location}" + }, + "toilet-charge": { + "question": "Wie viel muss man für diese Toiletten bezahlen?", + "render": "Die Gebühr beträgt {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Ein Wickeltisch ist verfügbar" + }, + "1": { + "then": "Es ist kein Wickeltisch verfügbar" + } + }, + "question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Dies sind bezahlte Toiletten" + }, + "1": { + "then": "Kostenlose Nutzung" + } + }, + "question": "Können diese Toiletten kostenlos benutzt werden?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Es gibt nur Sitztoiletten" + }, + "1": { + "then": "Hier gibt es nur Pissoirs" + }, + "2": { + "then": "Es gibt hier nur Hocktoiletten" + }, + "3": { + "then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar" + } + }, + "question": "Welche Art von Toiletten sind das?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Es gibt eine Toilette für Rollstuhlfahrer" + }, + "1": { + "then": "Kein Zugang für Rollstuhlfahrer" + } + }, + "question": "Gibt es eine Toilette für Rollstuhlfahrer?" } }, "title": { @@ -1271,7 +1257,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Möchten Sie eine Beschreibung hinzufügen?" } }, diff --git a/langs/layers/en.json b/langs/layers/en.json index 3a55d9b00..8900f0068 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -13,18 +13,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "A cyclist can go past this." - }, - "1": { - "then": "A cyclist can not go past this." - } - }, - "question": "Can a bicycle go past this barrier?" - }, - "1": { + "Bollard type": { "mappings": { "0": { "then": "Removable bollard" @@ -44,7 +33,7 @@ }, "question": "What kind of bollard is this?" }, - "2": { + "Cycle barrier type": { "mappings": { "0": { "then": "Single, just two barriers with a space inbetween " @@ -61,21 +50,32 @@ }, "question": "What kind of cycling barrier is this?" }, - "3": { + "MaxWidth": { "question": "How wide is the gap left over besides the barrier?", "render": "Maximum width: {maxwidth:physical} m" }, - "4": { + "Overlap (cyclebarrier)": { + "question": "How much overlap do the barriers have?", + "render": "Overlap: {overlap} m" + }, + "Space between barrier (cyclebarrier)": { "question": "How much space is there between the barriers (along the length of the road)?", "render": "Space between barriers (along the length of the road): {width:separation} m" }, - "5": { + "Width of opening (cyclebarrier)": { "question": "How wide is the smallest opening next to the barriers?", "render": "Width of opening: {width:opening} m" }, - "6": { - "question": "How much overlap do the barriers have?", - "render": "Overlap: {overlap} m" + "bicycle=yes/no": { + "mappings": { + "0": { + "then": "A cyclist can go past this." + }, + "1": { + "then": "A cyclist can not go past this." + } + }, + "question": "Can a bicycle go past this barrier?" } }, "title": { @@ -94,12 +94,11 @@ "name": "Benches", "presets": { "0": { - "description": "Add a new bench", - "title": "Bench" + "title": "bench" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Backrest: Yes" @@ -111,39 +110,7 @@ "question": "Does this bench have a backrest?", "render": "Backrest" }, - "2": { - "question": "How many seats does this bench have?", - "render": "{seats} seats" - }, - "3": { - "mappings": { - "0": { - "then": "Material: wood" - }, - "1": { - "then": "Material: metal" - }, - "2": { - "then": "Material: stone" - }, - "3": { - "then": "Material: concrete" - }, - "4": { - "then": "Material: plastic" - }, - "5": { - "then": "Material: steel" - } - }, - "question": "What is the bench (seating) made from?", - "render": "Material: {material}" - }, - "4": { - "question": "In which direction are you looking when sitting on the bench?", - "render": "When sitting on the bench, one looks towards {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Colour: brown" @@ -173,7 +140,39 @@ "question": "Which colour does this bench have?", "render": "Colour: {colour}" }, - "6": { + "bench-direction": { + "question": "In which direction are you looking when sitting on the bench?", + "render": "When sitting on the bench, one looks towards {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: wood" + }, + "1": { + "then": "Material: metal" + }, + "2": { + "then": "Material: stone" + }, + "3": { + "then": "Material: concrete" + }, + "4": { + "then": "Material: plastic" + }, + "5": { + "then": "Material: steel" + } + }, + "question": "What is the bench (seating) made from?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "How many seats does this bench have?", + "render": "{seats} seats" + }, + "bench-survey:date": { "question": "When was this bench last surveyed?", "render": "This bench was last surveyed on {survey:date}" } @@ -185,11 +184,11 @@ "bench_at_pt": { "name": "Benches at public transport stops", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Stand up bench" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -214,23 +213,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this bicycle library?", - "render": "This bicycle library is called {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Lending a bicycle is free" - }, - "1": { - "then": "Lending a bicycle costs €20/year and €20 warranty" - } - }, - "question": "How much does lending a bicycle cost?", - "render": "Lending a bicycle costs {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Bikes for children available" @@ -243,6 +226,22 @@ } }, "question": "Who can lend bicycles here?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Lending a bicycle is free" + }, + "1": { + "then": "Lending a bicycle costs €20/year and €20 warranty" + } + }, + "question": "How much does lending a bicycle cost?", + "render": "Lending a bicycle costs {charge}" + }, + "bicycle_library-name": { + "question": "What is the name of this bicycle library?", + "render": "This bicycle library is called {name}" } }, "title": { @@ -257,7 +256,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "This vending machine works" @@ -285,11 +284,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this bike cafe?", - "render": "This bike cafe is called {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "This bike cafe offers a bike pump for anyone" @@ -300,18 +295,20 @@ }, "question": "Does this bike cafe offer a bike pump for use by anyone?" }, - "3": { - "mappings": { - "0": { - "then": "This bike cafe offers tools for DIY repair" - }, - "1": { - "then": "This bike cafe doesn't offer tools for DIY repair" - } - }, - "question": "Are there tools here to repair your own bike?" + "bike_cafe-email": { + "question": "What is the email address of {name}?" }, - "4": { + "bike_cafe-name": { + "question": "What is the name of this bike cafe?", + "render": "This bike cafe is called {name}" + }, + "bike_cafe-opening_hours": { + "question": "When it this bike café opened?" + }, + "bike_cafe-phone": { + "question": "What is the phone number of {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "This bike cafe repairs bikes" @@ -322,17 +319,19 @@ }, "question": "Does this bike cafe repair bikes?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "This bike cafe offers tools for DIY repair" + }, + "1": { + "then": "This bike cafe doesn't offer tools for DIY repair" + } + }, + "question": "Are there tools here to repair your own bike?" + }, + "bike_cafe-website": { "question": "What is the website of {name}?" - }, - "6": { - "question": "What is the phone number of {name}?" - }, - "7": { - "question": "What is the email address of {name}?" - }, - "8": { - "question": "When it this bike café opened?" } }, "title": { @@ -360,20 +359,6 @@ "render": "Bike cleaning service" } }, - "bike_monitoring_station": { - "name": "Monitoring stations", - "title": { - "mappings": { - "0": { - "then": "Bicycle counting station {name}" - }, - "1": { - "then": "Bicycle counting station {ref}" - } - }, - "render": "Bicycle counting station" - } - }, "bike_parking": { "name": "Bike parking", "presets": { @@ -382,7 +367,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Publicly accessible" + }, + "1": { + "then": "Access is primarily for visitors to a business" + }, + "2": { + "then": "Access is limited to members of a school, company or organisation" + } + }, + "question": "Who can use this bicycle parking?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Staple racks " @@ -412,7 +412,40 @@ "question": "What is the type of this bicycle parking?", "render": "This is a bicycle parking of the type: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", + "render": "Place for {capacity} bikes" + }, + "Cargo bike capacity?": { + "question": "How many cargo bicycles fit in this bicycle parking?", + "render": "This parking fits {capacity:cargo_bike} cargo bikes" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "This parking has room for cargo bikes" + }, + "1": { + "then": "This parking has designated (official) spots for cargo bikes." + }, + "2": { + "then": "You're not allowed to park cargo bikes" + } + }, + "question": "Does this bicycle parking have spots for cargo bikes?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "This parking is covered (it has a roof)" + }, + "1": { + "then": "This parking is not covered" + } + }, + "question": "Is this parking covered? Also select \"covered\" for indoor parkings." + }, + "Underground?": { "mappings": { "0": { "then": "Underground parking" @@ -431,54 +464,6 @@ } }, "question": "What is the relative location of this bicycle parking?" - }, - "3": { - "mappings": { - "0": { - "then": "This parking is covered (it has a roof)" - }, - "1": { - "then": "This parking is not covered" - } - }, - "question": "Is this parking covered? Also select \"covered\" for indoor parkings." - }, - "4": { - "question": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", - "render": "Place for {capacity} bikes" - }, - "5": { - "mappings": { - "0": { - "then": "Publicly accessible" - }, - "1": { - "then": "Access is primarily for visitors to a business" - }, - "2": { - "then": "Access is limited to members of a school, company or organisation" - } - }, - "question": "Who can use this bicycle parking?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "This parking has room for cargo bikes" - }, - "1": { - "then": "This parking has designated (official) spots for cargo bikes." - }, - "2": { - "then": "You're not allowed to park cargo bikes" - } - }, - "question": "Does this bicycle parking have spots for cargo bikes?" - }, - "7": { - "question": "How many cargo bicycles fit in this bicycle parking?", - "render": "This parking fits {capacity:cargo_bike} cargo bikes" } }, "title": { @@ -504,7 +489,21 @@ } }, "tagRenderings": { - "1": { + "Email maintainer": { + "render": "Report this bicycle pump as broken" + }, + "Operational status": { + "mappings": { + "0": { + "then": "The bike pump is broken" + }, + "1": { + "then": "The bike pump is operational" + } + }, + "question": "Is the bike pump still operational?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "There is only a pump present" @@ -518,28 +517,7 @@ }, "question": "Which services are available at this bike station?" }, - "2": { - "question": "Who maintains this cycle pump?", - "render": "Maintained by {operator}" - }, - "3": { - "question": "What is the email address of the maintainer?" - }, - "4": { - "question": "What is the phone number of the maintainer?" - }, - "5": { - "mappings": { - "0": { - "then": "Always open" - }, - "1": { - "then": "Always open" - } - }, - "question": "When is this bicycle repair point open?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "There is a chain tool" @@ -550,7 +528,7 @@ }, "question": "Does this bike repair station have a special tool to repair your bike chain?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "There is a hook or stand" @@ -561,21 +539,53 @@ }, "question": "Does this bike station have a hook to hang your bike on or a stand to raise it?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "The bike pump is broken" + "then": "Manual pump" }, "1": { - "then": "The bike pump is operational" + "then": "Electrical pump" } }, - "question": "Is the bike pump still operational?" + "question": "Is this an electric bike pump?" }, - "9": { - "render": "Report this bicycle pump as broken" + "bike_repair_station-email": { + "question": "What is the email address of the maintainer?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "There is a manometer" + }, + "1": { + "then": "There is no manometer" + }, + "2": { + "then": "There is manometer but it is broken" + } + }, + "question": "Does the pump have a pressure indicator or manometer?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Always open" + }, + "1": { + "then": "Always open" + } + }, + "question": "When is this bicycle repair point open?" + }, + "bike_repair_station-operator": { + "question": "Who maintains this cycle pump?", + "render": "Maintained by {operator}" + }, + "bike_repair_station-phone": { + "question": "What is the phone number of the maintainer?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (also known as Presta)" @@ -589,31 +599,6 @@ }, "question": "What valves are supported?", "render": "This pump supports the following valves: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manual pump" - }, - "1": { - "then": "Electrical pump" - } - }, - "question": "Is this an electric bike pump?" - }, - "12": { - "mappings": { - "0": { - "then": "There is a manometer" - }, - "1": { - "then": "There is no manometer" - }, - "2": { - "then": "There is manometer but it is broken" - } - }, - "question": "Does the pump have a pressure indicator or manometer?" } }, "title": { @@ -646,34 +631,46 @@ } }, "tagRenderings": { - "1": { - "render": "This shop is specialized in selling {shop} and does bicycle related activities" - }, - "2": { - "question": "What is the name of this bicycle shop?", - "render": "This bicycle shop is called {name}" - }, - "3": { - "question": "What is the website of {name}?" - }, - "4": { - "question": "What is the phone number of {name}?" - }, - "5": { - "question": "What is the email address of {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "This shop sells bikes" + "then": "This shop offers a bike pump for anyone" }, "1": { - "then": "This shop doesn't sell bikes" + "then": "This shop doesn't offer a bike pump for anyone" + }, + "2": { + "then": "There is bicycle pump, it is shown as a separate point " } }, - "question": "Does this shop sell bikes?" + "question": "Does this shop offer a bike pump for use by anyone?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "This shop cleans bicycles" + }, + "1": { + "then": "This shop has an installation where one can clean bicycles themselves" + }, + "2": { + "then": "This shop doesn't offer bicycle cleaning" + } + }, + "question": "Are bicycles washed here?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "This shop rents out bikes" + }, + "1": { + "then": "This shop doesn't rent out bikes" + } + }, + "question": "Does this shop rent out bikes?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "This shop repairs bikes" @@ -690,18 +687,7 @@ }, "question": "Does this shop repair bikes?" }, - "11": { - "mappings": { - "0": { - "then": "This shop rents out bikes" - }, - "1": { - "then": "This shop doesn't rent out bikes" - } - }, - "question": "Does this shop rent out bikes?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "This shop sells second-hand bikes" @@ -715,21 +701,18 @@ }, "question": "Does this shop sell second-hand bikes?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "This shop offers a bike pump for anyone" + "then": "This shop sells bikes" }, "1": { - "then": "This shop doesn't offer a bike pump for anyone" - }, - "2": { - "then": "There is bicycle pump, it is shown as a separate point " + "then": "This shop doesn't sell bikes" } }, - "question": "Does this shop offer a bike pump for use by anyone?" + "question": "Does this shop sell bikes?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "This shop offers tools for DIY repair" @@ -743,19 +726,21 @@ }, "question": "Are there tools here to repair your own bike?" }, - "15": { - "mappings": { - "0": { - "then": "This shop cleans bicycles" - }, - "1": { - "then": "This shop has an installation where one can clean bicycles themselves" - }, - "2": { - "then": "This shop doesn't offer bicycle cleaning" - } - }, - "question": "Are bicycles washed here?" + "bike_shop-email": { + "question": "What is the email address of {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "This shop is specialized in selling {shop} and does bicycle related activities" + }, + "bike_shop-name": { + "question": "What is the name of this bicycle shop?", + "render": "This bicycle shop is called {name}" + }, + "bike_shop-phone": { + "question": "What is the phone number of {name}?" + }, + "bike_shop-website": { + "question": "What is the website of {name}?" } }, "title": { @@ -800,7 +785,7 @@ } }, "tagRenderings": { - "1": { + "binocular-charge": { "mappings": { "0": { "then": "Free to use" @@ -809,7 +794,7 @@ "question": "How much does one have to pay to use these binoculars?", "render": "Using these binoculars costs {charge}" }, - "2": { + "binocular-direction": { "question": "When looking through this binocular, in what direction does one look?", "render": "Looks towards {direction}°" } @@ -852,12 +837,12 @@ } }, "tagRenderings": { - "1": { + "Classification": { + "question": "What kind of cafe is this" + }, + "Name": { "question": "What is the name of this pub?", "render": "This pub is named {name}" - }, - "2": { - "question": "What kind of cafe is this" } }, "title": { @@ -922,6 +907,18 @@ }, "9": { "question": "Has a Type 2 CCS (mennekes) connector" + }, + "10": { + "question": "Has a Type 2 with cable (mennekes) connector" + }, + "11": { + "question": "Has a Tesla Supercharger CCS (a branded type2_css) connector" + }, + "12": { + "question": "Has a Tesla Supercharger (destination) connector" + }, + "13": { + "question": "Has a Tesla supercharger (destination (A Type 2 with cable branded as tesla) connector" } } } @@ -933,31 +930,40 @@ } }, "tagRenderings": { - "1": { + "Auth phone": { + "question": "What's the phone number for authentication call or SMS?", + "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" + }, + "Authentication": { "mappings": { "0": { - "then": "bicycles can be charged here" + "then": "Authentication by a membership card" }, "1": { - "then": "Cars can be charged here" + "then": "Authentication by an app" }, "2": { - "then": "Scooters can be charged here" + "then": "Authentication via phone call is available" }, "3": { - "then": "Heavy good vehicles (such as trucks) can be charged here" + "then": "Authentication via phone call is available" }, "4": { - "then": "Buses can be charged here" + "then": "Authentication via NFC is available" + }, + "5": { + "then": "Authentication via Money Card is available" + }, + "6": { + "then": "Authentication via debit card is available" + }, + "7": { + "then": "No authentication is needed" } }, - "question": "Which vehicles are allowed to charge here?" + "question": "What kind of authentication is available at the charging station?" }, - "3": { - "question": "How much vehicles can be charged here at the same time?", - "render": "{capacity} vehicles can be charged here at the same time" - }, - "4": { + "Available_charging_stations (generated)": { "mappings": { "0": { "then": "

Schuko wall plug without ground pin (CEE7/4 type F)

" @@ -1011,419 +1017,37 @@ "then": "

Type 2 CCS (mennekes)

" }, "17": { - "then": "

Type 2 CCS (mennekes)

" + "then": " Type 2 CCS (mennekes)" + }, + "18": { + "then": " Type 2 with cable (mennekes)" + }, + "19": { + "then": " Type 2 with cable (mennekes)" + }, + "20": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "21": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "22": { + "then": " Tesla Supercharger (destination)" + }, + "23": { + "then": " Tesla Supercharger (destination)" + }, + "24": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" + }, + "25": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" + } }, "question": "Which charging stations are available here?" }, - "5": { - "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" - } - }, - "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" - } - }, - "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" - }, - "9": { - "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" - }, - "10": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" - } - }, - "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" - }, - "1": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" - }, - "13": { - "question": "How much plugs of type Chademo are available here?", - "render": "There are Chademo plugs of type Chademo available here" - }, - "14": { - "mappings": { - "0": { - "then": "Chademo outputs 500 volt" - } - }, - "question": "What voltage do the plugs with Chademo offer?", - "render": "Chademo outputs {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": "Chademo outputs at most 120 A" - } - }, - "question": "What current do the plugs with Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": "Chademo outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:output}" - }, - "17": { - "question": "How much plugs of type Type 1 with cable (J1772) are available here?", - "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs at most 7 kw" - } - }, - "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" - }, - "21": { - "question": "How much plugs of type Type 1 without cable (J1772) are available here?", - "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" - }, - "2": { - "then": "Type 1 without cable (J1772) outputs at most 7 kw" - }, - "3": { - "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" - } - }, - "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" - }, - "25": { - "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" - }, - "26": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" - } - }, - "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" - } - }, - "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" - }, - "2": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" - }, - "3": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" - } - }, - "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" - }, - "29": { - "question": "How much plugs of type Tesla Supercharger are available here?", - "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" - }, - "30": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" - }, - "33": { - "question": "How much plugs of type Type 2 (mennekes) are available here?", - "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" - }, - "34": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" - }, - "37": { - "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" - }, - "38": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs 500 volt" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 125 A" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" - }, - "41": { - "mappings": { - "0": { - "then": "Authentication by a membership card" - }, - "1": { - "then": "Authentication by an app" - }, - "2": { - "then": "Authentication via phone call is available" - }, - "3": { - "then": "Authentication via phone call is available" - }, - "4": { - "then": "Authentication via NFC is available" - }, - "5": { - "then": "Authentication via Money Card is available" - }, - "6": { - "then": "Authentication via debit card is available" - }, - "7": { - "then": "No authentication is needed" - } - }, - "question": "What kind of authentication is available at the charging station?" - }, - "42": { - "question": "What's the phone number for authentication call or SMS?", - "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" - }, - "43": { - "mappings": { - "0": { - "then": "24/7 opened (including holidays)" - } - }, - "question": "When is this charging station opened?" - }, - "44": { - "mappings": { - "0": { - "then": "Free to use" - } - }, - "question": "How much does one have to pay to use this charging station?", - "render": "Using this charging station costs {charge}" - }, - "45": { - "override": { - "mappings+": { - "0": { - "then": "Payment is done using a dedicated app" - } - } - } - }, - "46": { - "mappings": { - "0": { - "then": "No timelimit on leaving your vehicle here" - } - }, - "question": "What is the maximum amount of time one is allowed to stay here?", - "render": "One can stay at most {canonical(maxstay)}" - }, - "47": { + "Network": { "mappings": { "0": { "then": "Not part of a bigger network" @@ -1435,22 +1059,15 @@ "question": "Is this charging station part of a network?", "render": "Part of the network {network}" }, - "49": { - "question": "What number can one call if there is a problem with this charging station?", - "render": "In case of problems, call {phone}" + "OH": { + "mappings": { + "0": { + "then": "24/7 opened (including holidays)" + } + }, + "question": "When is this charging station opened?" }, - "50": { - "question": "What is the email address of the operator?", - "render": "In case of problems, send an email to {email}" - }, - "51": { - "question": "What is the website of the operator?", - "render": "More info on {website}" - }, - "53": { - "question": "What is the reference number of this charging station?" - }, - "54": { + "Operational status": { "mappings": { "0": { "then": "This charging station is broken" @@ -1469,6 +1086,601 @@ } }, "question": "Is this charging point in use?" + }, + "Operator": { + "mappings": { + "0": { + "then": "Actually, {operator} is the network" + } + }, + "question": "Who is the operator of this charging station?", + "render": "This charging station is operated by {operator}" + }, + "Parking:fee": { + "mappings": { + "0": { + "then": "No additional parking cost while charging" + }, + "1": { + "then": "An additional parking fee should be paid while charging" + } + }, + "question": "Does one have to pay a parking fee while charging?" + }, + "Type": { + "mappings": { + "0": { + "then": "bicycles can be charged here" + }, + "1": { + "then": "Cars can be charged here" + }, + "2": { + "then": "Scooters can be charged here" + }, + "3": { + "then": "Heavy good vehicles (such as trucks) can be charged here" + }, + "4": { + "then": "Buses can be charged here" + } + }, + "question": "Which vehicles are allowed to charge here?" + }, + "13": { + "question": "How much plugs of type Chademo are available here?", + "render": "There are Chademo plugs of type Chademo available here" + }, + "current-0": { + "mappings": { + "0": { + "then": "Chademo outputs 500 volt" + } + }, + "question": "What voltage do the plugs with Chademo offer?", + "render": "Chademo outputs {socket:chademo:voltage} volt" + }, + "current-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" + } + }, + "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 120 A" + } + }, + "question": "What current do the plugs with Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" + } + }, + "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 125 A" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" + }, + "email": { + "question": "What is the email address of the operator?", + "render": "In case of problems, send an email to {email}" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Free to use" + } + }, + "question": "How much does one have to pay to use this charging station?", + "render": "Using this charging station costs {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "No timelimit on leaving your vehicle here" + } + }, + "question": "What is the maximum amount of time one is allowed to stay here?", + "render": "One can stay at most {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Payment is done using a dedicated app" + }, + "1": { + "then": "Payment is done using a membership card" + } + }, + "mappings+": { + "0": { + "then": "Payment is done using a dedicated app" + }, + "1": { + "then": "Payment is done using a membership card" + } + } + } + }, + "phone": { + "question": "What number can one call if there is a problem with this charging station?", + "render": "In case of problems, call {phone}" + }, + "plugs-0": { + "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" + }, + "plugs-1": { + "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" + }, + "plugs-10": { + "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" + }, + "plugs-11": { + "question": "How much plugs of type Tesla Supercharger (destination) are available here?", + "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" + }, + "plugs-12": { + "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" + }, + "plugs-2": { + "question": "How much plugs of type Chademo are available here?", + "render": "There are Chademo plugs of type Chademo available here" + }, + "plugs-3": { + "question": "How much plugs of type Type 1 with cable (J1772) are available here?", + "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" + }, + "plugs-4": { + "question": "How much plugs of type Type 1 without cable (J1772) are available here?", + "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" + }, + "plugs-5": { + "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" + }, + "plugs-6": { + "question": "How much plugs of type Tesla Supercharger are available here?", + "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" + }, + "plugs-7": { + "question": "How much plugs of type Type 2 (mennekes) are available here?", + "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" + }, + "plugs-8": { + "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" + }, + "plugs-9": { + "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" + } + }, + "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" + }, + "1": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger (destination) outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs at most 7 kw" + } + }, + "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" + }, + "2": { + "then": "Type 1 without cable (J1772) outputs at most 7 kw" + }, + "3": { + "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" + } + }, + "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" + }, + "2": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" + }, + "3": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" + } + }, + "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" + }, + "ref": { + "question": "What is the reference number of this charging station?", + "render": "Reference number is {ref}" + }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": "Chademo outputs 500 volt" + } + }, + "question": "What voltage do the plugs with Chademo offer?", + "render": "Chademo outputs {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" + } + }, + "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs 500 volt" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" + }, + "website": { + "question": "What is the website of the operator?", + "render": "More info on {website}" } }, "title": { @@ -1531,32 +1743,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Crossing, without traffic lights" - }, - "1": { - "then": "Crossing with traffic signals" - }, - "2": { - "then": "Zebra crossing" - } - }, - "question": "What kind of crossing is this?" - }, - "1": { - "mappings": { - "0": { - "then": "This is a zebra crossing" - }, - "1": { - "then": "This is not a zebra crossing" - } - }, - "question": "Is this is a zebra crossing?" - }, - "2": { + "crossing-bicycle-allowed": { "mappings": { "0": { "then": "A cyclist can use this crossing" @@ -1567,32 +1754,7 @@ }, "question": "Is this crossing also for bicycles?" }, - "3": { - "mappings": { - "0": { - "then": "This crossing has an island in the middle" - }, - "1": { - "then": "This crossing does not have an island in the middle" - } - }, - "question": "Does this crossing have an island in the middle?" - }, - "4": { - "mappings": { - "0": { - "then": "This crossing has tactile paving" - }, - "1": { - "then": "This crossing does not have tactile paving" - }, - "2": { - "then": "This crossing has tactile paving, but is not correct" - } - }, - "question": "Does this crossing have tactile paving?" - }, - "5": { + "crossing-button": { "mappings": { "0": { "then": "This traffic light has a button to request green light" @@ -1603,7 +1765,43 @@ }, "question": "Does this traffic light have a button to request green light?" }, - "6": { + "crossing-continue-through-red": { + "mappings": { + "0": { + "then": "A cyclist can go straight on if the light is red " + }, + "1": { + "then": "A cyclist can go straight on if the light is red" + }, + "2": { + "then": "A cyclist can not go straight on if the light is red" + } + }, + "question": "Can a cyclist go straight on when the light is red?" + }, + "crossing-has-island": { + "mappings": { + "0": { + "then": "This crossing has an island in the middle" + }, + "1": { + "then": "This crossing does not have an island in the middle" + } + }, + "question": "Does this crossing have an island in the middle?" + }, + "crossing-is-zebra": { + "mappings": { + "0": { + "then": "This is a zebra crossing" + }, + "1": { + "then": "This is not a zebra crossing" + } + }, + "question": "Is this is a zebra crossing?" + }, + "crossing-right-turn-through-red": { "mappings": { "0": { "then": "A cyclist can turn right if the light is red " @@ -1617,19 +1815,33 @@ }, "question": "Can a cyclist turn right when the light is red?" }, - "7": { + "crossing-tactile": { "mappings": { "0": { - "then": "A cyclist can go straight on if the light is red " + "then": "This crossing has tactile paving" }, "1": { - "then": "A cyclist can go straight on if the light is red" + "then": "This crossing does not have tactile paving" }, "2": { - "then": "A cyclist can not go straight on if the light is red" + "then": "This crossing has tactile paving, but is not correct" } }, - "question": "Can a cyclist go straight on when the light is red?" + "question": "Does this crossing have tactile paving?" + }, + "crossing-type": { + "mappings": { + "0": { + "then": "Crossing, without traffic lights" + }, + "1": { + "then": "Crossing with traffic signals" + }, + "2": { + "then": "Zebra crossing" + } + }, + "question": "What kind of crossing is this?" } }, "title": { @@ -1647,7 +1859,7 @@ "cycleways_and_roads": { "name": "Cycleways and roads", "tagRenderings": { - "0": { + "Cycleway type for a road": { "mappings": { "0": { "then": "There is a shared lane" @@ -1670,59 +1882,36 @@ }, "question": "What kind of cycleway is here?" }, - "1": { + "Cycleway:smoothness": { "mappings": { "0": { - "then": "This street is lit" + "then": "Usable for thin rollers: rollerblade, skateboard" }, "1": { - "then": "This road is not lit" + "then": "Usable for thin wheels: racing bike" }, "2": { - "then": "This road is lit at night" + "then": "Usable for normal wheels: city bike, wheelchair, scooter" }, "3": { - "then": "This road is lit 24/7" - } - }, - "question": "Is this street lit?" - }, - "2": { - "mappings": { - "0": { - "then": "This is a cyclestreet, and a 30km/h zone." - }, - "1": { - "then": "This is a cyclestreet" - }, - "2": { - "then": "This is not a cyclestreet." - } - }, - "question": "Is this a cyclestreet?" - }, - "3": { - "mappings": { - "0": { - "then": "The maximum speed is 20 km/h" - }, - "1": { - "then": "The maximum speed is 30 km/h" - }, - "2": { - "then": "The maximum speed is 50 km/h" - }, - "3": { - "then": "The maximum speed is 70 km/h" + "then": "Usable for robust wheels: trekking bike, car, rickshaw" }, "4": { - "then": "The maximum speed is 90 km/h" + "then": "Usable for vehicles with high clearance: light duty off-road vehicle" + }, + "5": { + "then": "Usable for off-road vehicles: heavy duty off-road vehicle" + }, + "6": { + "then": "Usable for specialized off-road vehicles: tractor, ATV" + }, + "7": { + "then": "Impassable / No wheeled vehicle" } }, - "question": "What is the maximum speed in this street?", - "render": "The maximum speed on this road is {maxspeed} km/h" + "question": "What is the smoothness of this cycleway?" }, - "4": { + "Cycleway:surface": { "mappings": { "0": { "then": "This cycleway is unpaved" @@ -1767,36 +1956,42 @@ "question": "What is the surface of the cycleway made from?", "render": "This cyleway is made of {cycleway:surface}" }, - "5": { + "Is this a cyclestreet? (For a road)": { "mappings": { "0": { - "then": "Usable for thin rollers: rollerblade, skateboard" + "then": "This is a cyclestreet, and a 30km/h zone." }, "1": { - "then": "Usable for thin wheels: racing bike" + "then": "This is a cyclestreet" }, "2": { - "then": "Usable for normal wheels: city bike, wheelchair, scooter" - }, - "3": { - "then": "Usable for robust wheels: trekking bike, car, rickshaw" - }, - "4": { - "then": "Usable for vehicles with high clearance: light duty off-road vehicle" - }, - "5": { - "then": "Usable for off-road vehicles: heavy duty off-road vehicle" - }, - "6": { - "then": "Usable for specialized off-road vehicles: tractor, ATV" - }, - "7": { - "then": "Impassable / No wheeled vehicle" + "then": "This is not a cyclestreet." } }, - "question": "What is the smoothness of this cycleway?" + "question": "Is this a cyclestreet?" }, - "6": { + "Maxspeed (for road)": { + "mappings": { + "0": { + "then": "The maximum speed is 20 km/h" + }, + "1": { + "then": "The maximum speed is 30 km/h" + }, + "2": { + "then": "The maximum speed is 50 km/h" + }, + "3": { + "then": "The maximum speed is 70 km/h" + }, + "4": { + "then": "The maximum speed is 90 km/h" + } + }, + "question": "What is the maximum speed in this street?", + "render": "The maximum speed on this road is {maxspeed} km/h" + }, + "Surface of the road": { "mappings": { "0": { "then": "This cycleway is unhardened" @@ -1841,7 +2036,7 @@ "question": "What is the surface of the street made from?", "render": "This road is made of {surface}" }, - "7": { + "Surface of the street": { "mappings": { "0": { "then": "Usable for thin rollers: rollerblade, skateboard" @@ -1870,11 +2065,24 @@ }, "question": "What is the smoothness of this street?" }, - "8": { - "question": "What is the carriage width of this road (in meters)?", - "render": "The carriage width of this road is {width:carriageway}m" + "cyclelan-segregation": { + "mappings": { + "0": { + "then": "This cycleway is separated by a dashed line" + }, + "1": { + "then": "This cycleway is separated by a solid line" + }, + "2": { + "then": "This cycleway is separated by a parking lane" + }, + "3": { + "then": "This cycleway is separated by a kerb" + } + }, + "question": "How is this cycleway separated from the road?" }, - "9": { + "cycleway-lane-track-traffic-signs": { "mappings": { "0": { "then": "Compulsory cycleway " @@ -1894,7 +2102,24 @@ }, "question": "What traffic sign does this cycleway have?" }, - "10": { + "cycleway-segregation": { + "mappings": { + "0": { + "then": "This cycleway is separated by a dashed line" + }, + "1": { + "then": "This cycleway is separated by a solid line" + }, + "2": { + "then": "This cycleway is separated by a parking lane" + }, + "3": { + "then": "This cycleway is separated by a kerb" + } + }, + "question": "How is this cycleway separated from the road?" + }, + "cycleway-traffic-signs": { "mappings": { "0": { "then": "Compulsory cycleway " @@ -1914,7 +2139,7 @@ }, "question": "What traffic sign does this cycleway have?" }, - "11": { + "cycleway-traffic-signs-D7-supplementary": { "mappings": { "0": { "then": "" @@ -1940,7 +2165,7 @@ }, "question": "Does the traffic sign D7 () have a supplementary sign?" }, - "12": { + "cycleway-traffic-signs-supplementary": { "mappings": { "0": { "then": "" @@ -1966,43 +2191,30 @@ }, "question": "Does the traffic sign D7 () have a supplementary sign?" }, - "13": { + "cycleways_and_roads-cycleway:buffer": { "question": "How wide is the gap between the cycleway and the road?", "render": "The buffer besides this cycleway is {cycleway:buffer} m" }, - "14": { + "is lit?": { "mappings": { "0": { - "then": "This cycleway is separated by a dashed line" + "then": "This street is lit" }, "1": { - "then": "This cycleway is separated by a solid line" + "then": "This road is not lit" }, "2": { - "then": "This cycleway is separated by a parking lane" + "then": "This road is lit at night" }, "3": { - "then": "This cycleway is separated by a kerb" + "then": "This road is lit 24/7" } }, - "question": "How is this cycleway separated from the road?" + "question": "Is this street lit?" }, - "15": { - "mappings": { - "0": { - "then": "This cycleway is separated by a dashed line" - }, - "1": { - "then": "This cycleway is separated by a solid line" - }, - "2": { - "then": "This cycleway is separated by a parking lane" - }, - "3": { - "then": "This cycleway is separated by a kerb" - } - }, - "question": "How is this cycleway separated from the road?" + "width:carriageway": { + "question": "What is the carriage width of this road (in meters)?", + "render": "The carriage width of this road is {width:carriageway}m" } }, "title": { @@ -2041,18 +2253,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This defibrillator is located indoors" - }, - "1": { - "then": "This defibrillator is located outdoors" - } - }, - "question": "Is this defibrillator located indoors?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Publicly accessible" @@ -2073,7 +2274,7 @@ "question": "Is this defibrillator freely accessible?", "render": "Access is {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "This is a manual defibrillator for professionals" @@ -2085,7 +2286,42 @@ "question": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", "render": "There is no info about the type of device" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Please give some explanation on where the defibrillator can be found (in the local language)", + "render": "Extra information about the location (in the local languagel):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Please give some explanation on where the defibrillator can be found (in English)", + "render": "Extra information about the location (in English):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Please give some explanation on where the defibrillator can be found (in French)", + "render": "Extra information about the location (in French):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", + "render": "Additional information: {description}" + }, + "defibrillator-email": { + "question": "What is the email for questions about this defibrillator?", + "render": "Email for questions about this defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", + "render": "Extra information for OpenStreetMap experts: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "This defibrillator is located indoors" + }, + "1": { + "then": "This defibrillator is located outdoors" + } + }, + "question": "Is this defibrillator located indoors?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "This defibrillator is on the ground floor" @@ -2097,31 +2333,7 @@ "question": "On which floor is this defibrillator located?", "render": "This defibrillator is on floor {level}" }, - "5": { - "question": "Please give some explanation on where the defibrillator can be found (in the local language)", - "render": "Extra information about the location (in the local languagel):
{defibrillator:location}" - }, - "6": { - "question": "Please give some explanation on where the defibrillator can be found (in English)", - "render": "Extra information about the location (in English):
{defibrillator:location:en}" - }, - "7": { - "question": "Please give some explanation on where the defibrillator can be found (in French)", - "render": "Extra information about the location (in French):
{defibrillator:location:fr}" - }, - "9": { - "question": "What is the official identification number of the device? (if visible on device)", - "render": "Official identification number of the device: {ref}" - }, - "10": { - "question": "What is the email for questions about this defibrillator?", - "render": "Email for questions about this defibrillator: {email}" - }, - "11": { - "question": "What is the phone number for questions about this defibrillator?", - "render": "Telephone for questions about this defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 opened (including holidays)" @@ -2130,11 +2342,15 @@ "question": "At what times is this defibrillator available?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", - "render": "Additional information: {description}" + "defibrillator-phone": { + "question": "What is the phone number for questions about this defibrillator?", + "render": "Telephone for questions about this defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "What is the official identification number of the device? (if visible on device)", + "render": "Official identification number of the device: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Checked today!" @@ -2142,10 +2358,6 @@ }, "question": "When was this defibrillator last surveyed?", "render": "This defibrillator was last surveyed on {survey:date}" - }, - "15": { - "question": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", - "render": "Extra information for OpenStreetMap experts: {fixme}" } }, "title": { @@ -2160,11 +2372,22 @@ "name": "Drinking water", "presets": { "0": { - "title": "Drinking water" + "title": "drinking water" } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "It is easy to refill water bottles" + }, + "1": { + "then": "Water bottles may not fit" + } + }, + "question": "How easy is it to fill water bottles?" + }, + "Still in use?": { "mappings": { "0": { "then": "This drinking water works" @@ -2179,18 +2402,7 @@ "question": "Is this drinking water spot still operational?", "render": "The operational status is {operational_status" }, - "2": { - "mappings": { - "0": { - "then": "It is easy to refill water bottles" - }, - "1": { - "then": "Water bottles may not fit" - } - }, - "question": "How easy is it to fill water bottles?" - }, - "3": { + "render-closest-drinking-water": { "render": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter" } }, @@ -2244,14 +2456,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this restaurant?", - "render": "The name of this restaurant is {name}" - }, - "2": { - "question": "What type of business is this?" - }, - "9": { + "Cuisine": { "mappings": { "0": { "then": "This is a pizzeria" @@ -2266,7 +2471,14 @@ "question": "Which food is served here?", "render": "This place mostly serves {cuisine}" }, - "10": { + "Fastfood vs restaurant": { + "question": "What type of business is this?" + }, + "Name": { + "question": "What is the name of this restaurant?", + "render": "The name of this restaurant is {name}" + }, + "Takeaway": { "mappings": { "0": { "then": "This is a take-away only business" @@ -2280,10 +2492,24 @@ }, "question": "Does this place offer takea-way?" }, - "11": { + "Vegetarian (no friture)": { "question": "Does this restaurant have a vegetarian option?" }, - "13": { + "friture-take-your-container": { + "mappings": { + "0": { + "then": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste" + }, + "1": { + "then": "Bringing your own container is not allowed" + }, + "2": { + "then": "You must bring your own container to order here." + } + }, + "question": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
" + }, + "halal (no friture)": { "mappings": { "0": { "then": "There are no halal options available" @@ -2299,20 +2525,6 @@ } }, "question": "Does this restaurant offer a halal menu?" - }, - "17": { - "mappings": { - "0": { - "then": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste" - }, - "1": { - "then": "Bringing your own container is not allowed" - }, - "2": { - "then": "You must bring your own container to order here." - } - }, - "question": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
" } }, "title": { @@ -2334,10 +2546,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location." }, - "2": { + "ghost_bike-inscription": { + "question": "What is the inscription on this Ghost bike?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "No name is marked on the bike" @@ -2346,15 +2562,11 @@ "question": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", "render": "In remembrance of {name}" }, - "3": { + "ghost_bike-source": { "question": "On what webpage can one find more information about the Ghost bike or the accident?", "render": "More information is available" }, - "4": { - "question": "What is the inscription on this Ghost bike?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "When was this Ghost bike installed?", "render": "Placed on {start_date}" } @@ -2372,7 +2584,7 @@ "name": "Information boards", "presets": { "0": { - "title": "Information board" + "title": "information board" } }, "title": { @@ -2389,16 +2601,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This map is based on OpenStreetMap" - } - }, - "question": "On which data is this map based?", - "render": "This map is based on {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "OpenStreetMap is clearly attributed, including the ODBL-license" @@ -2417,6 +2620,15 @@ } }, "question": "Is the OpenStreetMap-attribution given?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "This map is based on OpenStreetMap" + } + }, + "question": "On which data is this map based?", + "render": "This map is based on {map_source}" } }, "title": { @@ -2425,7 +2637,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", + "render": "{curator} is the curator of this nature reserve" + }, + "Dogs?": { "mappings": { "0": { "then": "Dogs have to be leashed" @@ -2439,23 +2655,19 @@ }, "question": "Are dogs allowed in this nature reserve?" }, - "6": { - "question": "On which webpage can one find more information about this nature reserve?" - }, - "7": { - "question": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", - "render": "{curator} is the curator of this nature reserve" - }, - "8": { + "Email": { "question": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Surface area: {_surface:ha}Ha" + }, + "Website": { + "question": "On which webpage can one find more information about this nature reserve?" + }, + "phone": { "question": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", "render": "{phone}" - }, - "12": { - "render": "Surface area: {_surface:ha}Ha" } } }, @@ -2468,24 +2680,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This tower doesn't have a specific name" - } - }, - "question": "What is the name of this tower?", - "render": "This tower is called {name}" - }, - "2": { - "question": "What is the height of this tower?", - "render": "This tower is {height} high" - }, - "3": { - "question": "Who maintains this tower?", - "render": "Maintained by {operator}" - }, - "5": { + "Fee": { "mappings": { "0": { "then": "Free to visit" @@ -2493,6 +2688,23 @@ }, "question": "How much does one have to pay to enter this tower?", "render": "Visiting this tower costs {charge}" + }, + "Height": { + "question": "What is the height of this tower?", + "render": "This tower is {height} high" + }, + "Operator": { + "question": "Who maintains this tower?", + "render": "Maintained by {operator}" + }, + "name": { + "mappings": { + "0": { + "then": "This tower doesn't have a specific name" + } + }, + "question": "What is the name of this tower?", + "render": "This tower is called {name}" } }, "title": { @@ -2518,11 +2730,11 @@ "name": "Picnic tables", "presets": { "0": { - "title": "Picnic table" + "title": "picnic table" } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "This is a wooden picnic table" @@ -2548,7 +2760,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Completely accessible for wheelchair users" + }, + "1": { + "then": "Limited accessibility for wheelchair users" + }, + "2": { + "then": "Not accessible for wheelchair users" + } + }, + "question": "Is this playground accessible to wheelchair users?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessible to the general public" + }, + "1": { + "then": "Accessible to the general public" + }, + "2": { + "then": "Only accessible for clients of the operating business" + }, + "3": { + "then": "Only accessible to students of the school" + }, + "4": { + "then": "Not accessible" + } + }, + "question": "Is this playground accessible to the general public?" + }, + "playground-email": { + "question": "What is the email address of the playground maintainer?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "This playground is lit at night" + }, + "1": { + "then": "This playground is not lit at night" + } + }, + "question": "Is this playground lit at night?" + }, + "playground-max_age": { + "question": "What is the maximum age allowed to access this playground?", + "render": "Accessible to kids of at most {max_age}" + }, + "playground-min_age": { + "question": "What is the minimum age required to access this playground?", + "render": "Accessible to kids older than {min_age} years" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Accessible from sunrise till sunset" + }, + "1": { + "then": "Always accessible" + }, + "2": { + "then": "Always accessible" + } + }, + "question": "When is this playground accessible?" + }, + "playground-operator": { + "question": "Who operates this playground?", + "render": "Operated by {operator}" + }, + "playground-phone": { + "question": "What is the phone number of the playground maintainer?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -2577,85 +2868,6 @@ }, "question": "Which is the surface of this playground?
If there are multiple, select the most occuring one", "render": "The surface is {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "This playground is lit at night" - }, - "1": { - "then": "This playground is not lit at night" - } - }, - "question": "Is this playground lit at night?" - }, - "3": { - "question": "What is the minimum age required to access this playground?", - "render": "Accessible to kids older than {min_age} years" - }, - "4": { - "question": "What is the maximum age allowed to access this playground?", - "render": "Accessible to kids of at most {max_age}" - }, - "5": { - "question": "Who operates this playground?", - "render": "Operated by {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessible to the general public" - }, - "1": { - "then": "Accessible to the general public" - }, - "2": { - "then": "Only accessible for clients of the operating business" - }, - "3": { - "then": "Only accessible to students of the school" - }, - "4": { - "then": "Not accessible" - } - }, - "question": "Is this playground accessible to the general public?" - }, - "7": { - "question": "What is the email address of the playground maintainer?", - "render": "{email}" - }, - "8": { - "question": "What is the phone number of the playground maintainer?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Completely accessible for wheelchair users" - }, - "1": { - "then": "Limited accessibility for wheelchair users" - }, - "2": { - "then": "Not accessible for wheelchair users" - } - }, - "question": "Is this playground accessible to wheelchair users?" - }, - "10": { - "mappings": { - "0": { - "then": "Accessible from sunrise till sunset" - }, - "1": { - "then": "Always accessible" - }, - "2": { - "then": "Always accessible" - } - }, - "question": "When is this playground accessible?" } }, "title": { @@ -2669,6 +2881,15 @@ }, "public_bookcase": { "description": "A streetside cabinet with books, accessible to anyone", + "filter": { + "2": { + "options": { + "0": { + "question": "Indoor or outdoor" + } + } + } + }, "name": "Bookcases", "presets": { "0": { @@ -2676,20 +2897,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "This bookcase doesn't have a name" - } - }, - "question": "What is the name of this public bookcase?", - "render": "The name of this bookcase is {name}" - }, - "3": { - "question": "How many books fit into this public bookcase?", - "render": "{capacity} books fit in this bookcase" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Mostly children books" @@ -2703,7 +2911,18 @@ }, "question": "What kind of books can be found in this public bookcase?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Publicly accessible" + }, + "1": { + "then": "Only accessible to customers" + } + }, + "question": "Is this public bookcase freely accessible?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "This bookcase is located indoors" @@ -2717,22 +2936,7 @@ }, "question": "Is this bookcase located outdoors?" }, - "6": { - "mappings": { - "0": { - "then": "Publicly accessible" - }, - "1": { - "then": "Only accessible to customers" - } - }, - "question": "Is this public bookcase freely accessible?" - }, - "7": { - "question": "Who maintains this public bookcase?", - "render": "Operated by {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Part of the network 'Little Free Library'" @@ -2744,7 +2948,24 @@ "question": "Is this public bookcase part of a bigger network?", "render": "This public bookcase is part of {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "How many books fit into this public bookcase?", + "render": "{capacity} books fit in this bookcase" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "This bookcase doesn't have a name" + } + }, + "question": "What is the name of this public bookcase?", + "render": "The name of this bookcase is {name}" + }, + "public_bookcase-operator": { + "question": "Who maintains this public bookcase?", + "render": "Operated by {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "This bookcase is not part of a bigger network" @@ -2753,11 +2974,11 @@ "question": "What is the reference number of this public bookcase?", "render": "The reference number of this public bookcase within {brand} is {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "When was this public bookcase installed?", "render": "Installed on {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Is there a website with more information about this public bookcase?", "render": "More info on the website" } @@ -2773,7 +2994,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -2816,7 +3037,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Public access" + }, + "1": { + "then": "Limited access (e.g. only with an appointment, during certain hours, ...)" + }, + "2": { + "then": "Only accessible for members of the club" + }, + "3": { + "then": "Private - not accessible to the public" + } + }, + "question": "Is this sport pitch publicly accessible?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Making an appointment is obligatory to use this sport pitch" + }, + "1": { + "then": "Making an appointment is recommended when using this sport pitch" + }, + "2": { + "then": "Making an appointment is possible, but not necessary to use this sport pitch" + }, + "3": { + "then": "Making an appointment is not possible" + } + }, + "question": "Does one have to make an appointment to use this sport pitch?" + }, + "sport_pitch-email": { + "question": "What is the email address of the operator?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Always accessible" + } + }, + "question": "When is this pitch accessible?" + }, + "sport_pitch-phone": { + "question": "What is the phone number of the operator?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Basketball is played here" @@ -2840,7 +3109,7 @@ "question": "Which sport can be played here?", "render": "{sport} is played here" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -2860,54 +3129,6 @@ }, "question": "Which is the surface of this sport pitch?", "render": "The surface is {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Public access" - }, - "1": { - "then": "Limited access (e.g. only with an appointment, during certain hours, ...)" - }, - "2": { - "then": "Only accessible for members of the club" - }, - "3": { - "then": "Private - not accessible to the public" - } - }, - "question": "Is this sport pitch publicly accessible?" - }, - "4": { - "mappings": { - "0": { - "then": "Making an appointment is obligatory to use this sport pitch" - }, - "1": { - "then": "Making an appointment is recommended when using this sport pitch" - }, - "2": { - "then": "Making an appointment is possible, but not necessary to use this sport pitch" - }, - "3": { - "then": "Making an appointment is not possible" - } - }, - "question": "Does one have to make an appointment to use this sport pitch?" - }, - "5": { - "question": "What is the phone number of the operator?" - }, - "6": { - "question": "What is the email address of the operator?" - }, - "7": { - "mappings": { - "1": { - "then": "Always accessible" - } - }, - "question": "When is this pitch accessible?" } }, "title": { @@ -2917,7 +3138,7 @@ "surveillance_camera": { "name": "Surveillance camera's", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "A fixed (non-moving) camera" @@ -2931,34 +3152,7 @@ }, "question": "What kind of camera is this?" }, - "2": { - "mappings": { - "0": { - "then": "Films to a compass heading of {direction}" - } - }, - "question": "In which geographical direction does this camera film?", - "render": "Films to a compass heading of {camera:direction}" - }, - "3": { - "question": "Who operates this CCTV?", - "render": "Operated by {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,..." - }, - "1": { - "then": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)" - }, - "2": { - "then": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ..." - } - }, - "question": "What kind of surveillance is this camera" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "This camera is located indoors" @@ -2972,11 +3166,29 @@ }, "question": "Is the public space surveilled by this camera an indoor or outdoor space?" }, - "6": { + "Level": { "question": "On which level is this camera located?", "render": "Located on level {level}" }, - "7": { + "Operator": { + "question": "Who operates this CCTV?", + "render": "Operated by {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,..." + }, + "1": { + "then": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)" + }, + "2": { + "then": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ..." + } + }, + "question": "What kind of surveillance is this camera" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Surveills a parking" @@ -3000,7 +3212,7 @@ "question": "What exactly is surveilled here?", "render": " Surveills a {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "This camera is placed against a wall" @@ -3014,6 +3226,15 @@ }, "question": "How is this camera placed?", "render": "Mounting method: {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Films to a compass heading of {direction}" + } + }, + "question": "In which geographical direction does this camera film?", + "render": "Films to a compass heading of {camera:direction}" } }, "title": { @@ -3048,15 +3269,15 @@ "presets": { "0": { "description": "A publicly accessible toilet or restroom", - "title": "Toilet" + "title": "toilet" }, "1": { "description": "A restroom which has at least one wheelchair-accessible toilet", - "title": "Toilets with wheelchair accessible toilet" + "title": "toilets with wheelchair accessible toilet" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Public access" @@ -3077,61 +3298,7 @@ "question": "Are these toilets publicly accessible?", "render": "Access is {access}" }, - "2": { - "mappings": { - "0": { - "then": "These are paid toilets" - }, - "1": { - "then": "Free to use" - } - }, - "question": "Are these toilets free to use?" - }, - "3": { - "question": "How much does one have to pay for these toilets?", - "render": "The fee is {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "There is a dedicated toilet for wheelchair users" - }, - "1": { - "then": "No wheelchair access" - } - }, - "question": "Is there a dedicated toilet for wheelchair users" - }, - "5": { - "mappings": { - "0": { - "then": "There are only seated toilets" - }, - "1": { - "then": "There are only urinals here" - }, - "2": { - "then": "There are only squat toilets here" - }, - "3": { - "then": "Both seated toilets and urinals are available here" - } - }, - "question": "Which kind of toilets are this?" - }, - "6": { - "mappings": { - "0": { - "then": "A changing table is available" - }, - "1": { - "then": "No changing table is available" - } - }, - "question": "Is a changing table (to change diapers) available?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "The changing table is in the toilet for women. " @@ -3148,6 +3315,82 @@ }, "question": "Where is the changing table located?", "render": "The changing table is located at {changing_table:location}" + }, + "toilet-charge": { + "question": "How much does one have to pay for these toilets?", + "render": "The fee is {charge}" + }, + "toilet-handwashing": { + "mappings": { + "0": { + "then": "This toilets have a sink to wash your hands" + }, + "1": { + "then": "This toilets don't have a sink to wash your hands" + } + }, + "question": "Do these toilets have a sink to wash your hands?" + }, + "toilet-has-paper": { + "mappings": { + "0": { + "then": "Toilet paper is equipped with toilet paper" + }, + "1": { + "then": "You have to bring your own toilet paper to this toilet" + } + }, + "question": "Does one have to bring their own toilet paper to this toilet?" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "A changing table is available" + }, + "1": { + "then": "No changing table is available" + } + }, + "question": "Is a changing table (to change diapers) available?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "These are paid toilets" + }, + "1": { + "then": "Free to use" + } + }, + "question": "Are these toilets free to use?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "There are only seated toilets" + }, + "1": { + "then": "There are only urinals here" + }, + "2": { + "then": "There are only squat toilets here" + }, + "3": { + "then": "Both seated toilets and urinals are available here" + } + }, + "question": "Which kind of toilets are this?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "There is a dedicated toilet for wheelchair users" + }, + "1": { + "then": "No wheelchair access" + } + }, + "question": "Is there a dedicated toilet for wheelchair users" } }, "title": { @@ -3157,10 +3400,7 @@ "trail": { "name": "Trails", "tagRenderings": { - "1": { - "render": "The trail is {_length:km} kilometers long" - }, - "4": { + "Color": { "mappings": { "0": { "then": "Blue trail" @@ -3175,6 +3415,9 @@ "then": "Yellow trail" } } + }, + "trail-length": { + "render": "The trail is {_length:km} kilometers long" } }, "title": { @@ -3198,29 +3441,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Height: {height} m" - } - }, - "render": "Height: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Broadleaved" + "then": "Deciduous: the tree loses its leaves for some time of the year." }, "1": { - "then": "\"\"/ Needleleaved" - }, - "2": { - "then": "\"\"/ Permanently leafless" + "then": "Evergreen." } }, - "question": "Is this a broadleaved or needleleaved tree?" + "question": "Is this tree evergreen or deciduous?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "The tree is remarkable due to its size or prominent location. It is useful for navigation." @@ -3249,27 +3481,15 @@ }, "question": "How significant is this tree? Choose the first answer that applies." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Deciduous: the tree loses its leaves for some time of the year." - }, - "1": { - "then": "Evergreen." + "then": "Height: {height} m" } }, - "question": "Is this tree evergreen or deciduous?" + "render": "Height: {height}" }, - "5": { - "mappings": { - "0": { - "then": "The tree does not have a name." - } - }, - "question": "Does the tree have a name?", - "render": "Name: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders" @@ -3289,11 +3509,34 @@ }, "question": "Is this tree registered heritage?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Broadleaved" + }, + "1": { + "then": "\"\"/ Needleleaved" + }, + "2": { + "then": "\"\"/ Permanently leafless" + } + }, + "question": "Is this a broadleaved or needleleaved tree?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "The tree does not have a name." + } + }, + "question": "Does the tree have a name?", + "render": "Name: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "What is the ID issued by Onroerend Erfgoed Flanders?", "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "What is the Wikidata ID for this tree?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -3316,7 +3559,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Do you want to add a description?" } }, @@ -3352,7 +3595,7 @@ } }, "tagRenderings": { - "0": { + "waste-basket-waste-types": { "mappings": { "0": { "then": "A waste basket for general waste" diff --git a/langs/layers/es.json b/langs/layers/es.json index 2b1005bef..44e99ca4c 100644 --- a/langs/layers/es.json +++ b/langs/layers/es.json @@ -3,12 +3,11 @@ "name": "Bancos", "presets": { "0": { - "description": "Añadir un nuevo banco", - "title": "Banco" + "title": "banco" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Respaldo: Si" @@ -20,11 +19,7 @@ "question": "¿Este banco tiene un respaldo?", "render": "Respaldo" }, - "2": { - "question": "¿Cuántos asientos tiene este banco?", - "render": "{seats} asientos" - }, - "3": { + "bench-material": { "mappings": { "0": { "then": "Material: madera" @@ -46,6 +41,10 @@ } }, "render": "Material: {material}" + }, + "bench-seats": { + "question": "¿Cuántos asientos tiene este banco?", + "render": "{seats} asientos" } }, "title": { @@ -66,18 +65,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Este desfibrilador está en interior" - }, - "1": { - "then": "Este desfibrilador está en exterior" - } - }, - "question": "¿Esté el desfibrilador en interior?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Acceso libre" @@ -95,18 +83,29 @@ "question": "¿Está el desfibrilador accesible libremente?", "render": "El acceso es {access}" }, - "4": { - "question": "¿En qué planta se encuentra el defibrilador localizado?", - "render": "El desfibrilador se encuentra en la planta {level}" - }, - "5": { + "defibrillator-defibrillator:location": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)" }, - "6": { + "defibrillator-defibrillator:location:en": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)" }, - "7": { + "defibrillator-defibrillator:location:fr": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Este desfibrilador está en interior" + }, + "1": { + "then": "Este desfibrilador está en exterior" + } + }, + "question": "¿Esté el desfibrilador en interior?" + }, + "defibrillator-level": { + "question": "¿En qué planta se encuentra el defibrilador localizado?", + "render": "El desfibrilador se encuentra en la planta {level}" } }, "title": { diff --git a/langs/layers/fi.json b/langs/layers/fi.json index 3499be2da..a13231cd6 100644 --- a/langs/layers/fi.json +++ b/langs/layers/fi.json @@ -3,12 +3,11 @@ "name": "Penkit", "presets": { "0": { - "description": "Lisää uusi penkki", - "title": "Penkki" + "title": "penkki" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Selkänoja: kyllä" @@ -19,27 +18,7 @@ }, "render": "Selkänoja" }, - "3": { - "mappings": { - "0": { - "then": "Materiaali: puu" - }, - "2": { - "then": "Materiaali: kivi" - }, - "3": { - "then": "Materiaali: betoni" - }, - "4": { - "then": "Materiaali: muovi" - }, - "5": { - "then": "Materiaali: teräs" - } - }, - "render": "Materiaali: {material}" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Väri: ruskea" @@ -67,6 +46,26 @@ } }, "render": "Väri: {colour}" + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiaali: puu" + }, + "2": { + "then": "Materiaali: kivi" + }, + "3": { + "then": "Materiaali: betoni" + }, + "4": { + "then": "Materiaali: muovi" + }, + "5": { + "then": "Materiaali: teräs" + } + }, + "render": "Materiaali: {material}" } }, "title": { @@ -75,7 +74,7 @@ }, "bench_at_pt": { "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -85,7 +84,7 @@ }, "bike_parking": { "tagRenderings": { - "5": { + "Access": { "render": "{access}" } } diff --git a/langs/layers/fr.json b/langs/layers/fr.json index 2c27049e9..52c61d899 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -3,12 +3,11 @@ "name": "Bancs", "presets": { "0": { - "description": "Ajouter un nouveau banc", - "title": "Banc" + "title": "banc" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Dossier : Oui" @@ -20,39 +19,7 @@ "question": "Ce banc dispose-t-il d'un dossier ?", "render": "Dossier" }, - "2": { - "question": "De combien de places dispose ce banc ?", - "render": "{seats} places" - }, - "3": { - "mappings": { - "0": { - "then": "Matériau : bois" - }, - "1": { - "then": "Matériau : métal" - }, - "2": { - "then": "Matériau : pierre" - }, - "3": { - "then": "Matériau : béton" - }, - "4": { - "then": "Matériau : plastique" - }, - "5": { - "then": "Matériau : acier" - } - }, - "question": "De quel matériau ce banc est-il fait ?", - "render": "Matériau : {material}" - }, - "4": { - "question": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", - "render": "Assis sur le banc, on regarde vers {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Couleur : marron" @@ -82,7 +49,39 @@ "question": "Quelle est la couleur de ce banc ?", "render": "Couleur : {colour}" }, - "6": { + "bench-direction": { + "question": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", + "render": "Assis sur le banc, on regarde vers {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Matériau : bois" + }, + "1": { + "then": "Matériau : métal" + }, + "2": { + "then": "Matériau : pierre" + }, + "3": { + "then": "Matériau : béton" + }, + "4": { + "then": "Matériau : plastique" + }, + "5": { + "then": "Matériau : acier" + } + }, + "question": "De quel matériau ce banc est-il fait ?", + "render": "Matériau : {material}" + }, + "bench-seats": { + "question": "De combien de places dispose ce banc ?", + "render": "{seats} places" + }, + "bench-survey:date": { "question": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", "render": "Ce banc a été contrôlé pour la dernière fois le {survey:date}" } @@ -94,11 +93,11 @@ "bench_at_pt": { "name": "Bancs des arrêts de transport en commun", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Banc assis debout" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +122,7 @@ } }, "tagRenderings": { - "1": { - "question": "Quel est le nom de cette vélothèque ?", - "render": "Cette vélothèque s'appelle {name}" - }, - "6": { - "mappings": { - "0": { - "then": "L'emprunt de vélo est gratuit" - }, - "1": { - "then": "Emprunter un vélo coûte 20 €/an et 20 € de garantie" - } - }, - "question": "Combien coûte l'emprunt d'un vélo ?", - "render": "Emprunter un vélo coûte {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Vélos pour enfants disponibles" @@ -152,6 +135,22 @@ } }, "question": "Qui peut emprunter des vélos ici ?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "L'emprunt de vélo est gratuit" + }, + "1": { + "then": "Emprunter un vélo coûte 20 €/an et 20 € de garantie" + } + }, + "question": "Combien coûte l'emprunt d'un vélo ?", + "render": "Emprunter un vélo coûte {charge}" + }, + "bicycle_library-name": { + "question": "Quel est le nom de cette vélothèque ?", + "render": "Cette vélothèque s'appelle {name}" } }, "title": { @@ -166,7 +165,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Le distributeur automatique fonctionne" @@ -194,11 +193,7 @@ } }, "tagRenderings": { - "1": { - "question": "Quel est le nom de ce Café vélo ?", - "render": "Ce Café vélo s'appelle {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Ce Café vélo offre une pompe en libre accès" @@ -209,18 +204,20 @@ }, "question": "Est-ce que ce Café vélo propose une pompe en libre accès ?" }, - "3": { - "mappings": { - "0": { - "then": "Ce Café vélo propose des outils pour réparer son vélo soi-même" - }, - "1": { - "then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même" - } - }, - "question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?" + "bike_cafe-email": { + "question": "Quelle est l'adresse électronique de {name} ?" }, - "4": { + "bike_cafe-name": { + "question": "Quel est le nom de ce Café vélo ?", + "render": "Ce Café vélo s'appelle {name}" + }, + "bike_cafe-opening_hours": { + "question": "Quand ce Café vélo est-t-il ouvert ?" + }, + "bike_cafe-phone": { + "question": "Quel est le numéro de téléphone de {name} ?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Ce Café vélo répare les vélos" @@ -231,17 +228,19 @@ }, "question": "Est-ce que ce Café vélo répare les vélos ?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Ce Café vélo propose des outils pour réparer son vélo soi-même" + }, + "1": { + "then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même" + } + }, + "question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?" + }, + "bike_cafe-website": { "question": "Quel est le site web de {name} ?" - }, - "6": { - "question": "Quel est le numéro de téléphone de {name} ?" - }, - "7": { - "question": "Quelle est l'adresse électronique de {name} ?" - }, - "8": { - "question": "Quand ce Café vélo est-t-il ouvert ?" } }, "title": { @@ -269,20 +268,6 @@ "render": "Service de nettoyage de vélo" } }, - "bike_monitoring_station": { - "name": "Stations de contrôle", - "title": { - "mappings": { - "0": { - "then": "Station de comptage de vélo {name}" - }, - "1": { - "then": "Station de comptage de vélo {ref}" - } - }, - "render": "Station de comptage de vélo" - } - }, "bike_parking": { "name": "Parking à vélo", "presets": { @@ -291,7 +276,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Accessible publiquement" + }, + "1": { + "then": "Accès destiné principalement aux visiteurs d'un lieu" + }, + "2": { + "then": "Accès limité aux membres d'une école, entreprise ou organisation" + } + }, + "question": "Qui peut utiliser ce parking à vélo ?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Arceaux " @@ -321,7 +321,40 @@ "question": "Quel type de parking à vélos est-ce ?", "render": "Ceci est un parking à vélo de type {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", + "render": "Place pour {capacity} vélos" + }, + "Cargo bike capacity?": { + "question": "Combien de vélos de transport entrent dans ce parking à vélos ?", + "render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Ce parking a de la place pour les vélos cargo" + }, + "1": { + "then": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo." + }, + "2": { + "then": "Il est interdit de garer des vélos cargo" + } + }, + "question": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Ce parking est couvert (il a un toit)" + }, + "1": { + "then": "Ce parking n'est pas couvert" + } + }, + "question": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur." + }, + "Underground?": { "mappings": { "0": { "then": "Parking souterrain" @@ -340,54 +373,6 @@ } }, "question": "Quelle est la position relative de ce parking à vélo ?" - }, - "3": { - "mappings": { - "0": { - "then": "Ce parking est couvert (il a un toit)" - }, - "1": { - "then": "Ce parking n'est pas couvert" - } - }, - "question": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur." - }, - "4": { - "question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", - "render": "Place pour {capacity} vélos" - }, - "5": { - "mappings": { - "0": { - "then": "Accessible publiquement" - }, - "1": { - "then": "Accès destiné principalement aux visiteurs d'un lieu" - }, - "2": { - "then": "Accès limité aux membres d'une école, entreprise ou organisation" - } - }, - "question": "Qui peut utiliser ce parking à vélo ?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Ce parking a de la place pour les vélos cargo" - }, - "1": { - "then": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo." - }, - "2": { - "then": "Il est interdit de garer des vélos cargo" - } - }, - "question": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?" - }, - "7": { - "question": "Combien de vélos de transport entrent dans ce parking à vélos ?", - "render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport" } }, "title": { @@ -413,7 +398,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "La pompe à vélo est cassée" + }, + "1": { + "then": "La pompe est opérationnelle" + } + }, + "question": "La pompe à vélo fonctionne-t-elle toujours ?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Il y a seulement une pompe" @@ -427,22 +423,7 @@ }, "question": "Quels services sont valables à cette station vélo ?" }, - "2": { - "question": "Qui maintient cette pompe à vélo ?", - "render": "Mantenue par {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Ouvert en permanence" - }, - "1": { - "then": "Ouvert en permanence" - } - }, - "question": "Quand ce point de réparation de vélo est-il ouvert ?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Il y a un outil pour réparer la chaine" @@ -453,7 +434,7 @@ }, "question": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Il y a un crochet ou une accroche" @@ -464,18 +445,47 @@ }, "question": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "La pompe à vélo est cassée" + "then": "Pompe manuelle" }, "1": { - "then": "La pompe est opérationnelle" + "then": "Pompe électrique" } }, - "question": "La pompe à vélo fonctionne-t-elle toujours ?" + "question": "Est-ce que cette pompe est électrique ?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Il y a un manomètre" + }, + "1": { + "then": "Il n'y a pas de manomètre" + }, + "2": { + "then": "Il y a un manomètre mais il est cassé" + } + }, + "question": "Est-ce que la pompe à un manomètre integré ?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Ouvert en permanence" + }, + "1": { + "then": "Ouvert en permanence" + } + }, + "question": "Quand ce point de réparation de vélo est-il ouvert ?" + }, + "bike_repair_station-operator": { + "question": "Qui maintient cette pompe à vélo ?", + "render": "Mantenue par {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (aussi appelé Presta)" @@ -489,31 +499,6 @@ }, "question": "Quelles valves sont compatibles ?", "render": "Cette pompe est compatible avec les valves suivantes : {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Pompe manuelle" - }, - "1": { - "then": "Pompe électrique" - } - }, - "question": "Est-ce que cette pompe est électrique ?" - }, - "12": { - "mappings": { - "0": { - "then": "Il y a un manomètre" - }, - "1": { - "then": "Il n'y a pas de manomètre" - }, - "2": { - "then": "Il y a un manomètre mais il est cassé" - } - }, - "question": "Est-ce que la pompe à un manomètre integré ?" } }, "title": { @@ -546,34 +531,46 @@ } }, "tagRenderings": { - "1": { - "render": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo" - }, - "2": { - "question": "Quel est le nom du magasin de vélos ?", - "render": "Ce magasin s'appelle {name}" - }, - "3": { - "question": "Quel est le site web de {name} ?" - }, - "4": { - "question": "Quel est le numéro de téléphone de {name} ?" - }, - "5": { - "question": "Quelle est l'adresse électronique de {name} ?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Ce magasin vend des vélos" + "then": "Ce magasin offre une pompe en acces libre" }, "1": { - "then": "Ce magasin ne vend pas de vélo" + "then": "Ce magasin n'offre pas de pompe en libre accès" + }, + "2": { + "then": "Il y a une pompe à vélo, c'est indiqué comme un point séparé " } }, - "question": "Est-ce que ce magasin vend des vélos ?" + "question": "Est-ce que ce magasin offre une pompe en accès libre ?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Ce magasin lave les vélos" + }, + "1": { + "then": "Ce magasin a une installation pour laver soi même des vélos" + }, + "2": { + "then": "Ce magasin ne fait pas le nettoyage de vélo" + } + }, + "question": "Lave-t-on les vélos ici ?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Ce magasin loue des vélos" + }, + "1": { + "then": "Ce magasin ne loue pas de vélos" + } + }, + "question": "Est-ce ce magasin loue des vélos ?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Ce magasin répare des vélos" @@ -590,18 +587,7 @@ }, "question": "Est-ce que ce magasin répare des vélos ?" }, - "11": { - "mappings": { - "0": { - "then": "Ce magasin loue des vélos" - }, - "1": { - "then": "Ce magasin ne loue pas de vélos" - } - }, - "question": "Est-ce ce magasin loue des vélos ?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Ce magasin vend des vélos d'occasion" @@ -615,21 +601,18 @@ }, "question": "Est-ce ce magasin vend des vélos d'occasion ?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Ce magasin offre une pompe en acces libre" + "then": "Ce magasin vend des vélos" }, "1": { - "then": "Ce magasin n'offre pas de pompe en libre accès" - }, - "2": { - "then": "Il y a une pompe à vélo, c'est indiqué comme un point séparé " + "then": "Ce magasin ne vend pas de vélo" } }, - "question": "Est-ce que ce magasin offre une pompe en accès libre ?" + "question": "Est-ce que ce magasin vend des vélos ?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Ce magasin offre des outils pour réparer son vélo soi-même" @@ -643,19 +626,21 @@ }, "question": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?" }, - "15": { - "mappings": { - "0": { - "then": "Ce magasin lave les vélos" - }, - "1": { - "then": "Ce magasin a une installation pour laver soi même des vélos" - }, - "2": { - "then": "Ce magasin ne fait pas le nettoyage de vélo" - } - }, - "question": "Lave-t-on les vélos ici ?" + "bike_shop-email": { + "question": "Quelle est l'adresse électronique de {name} ?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo" + }, + "bike_shop-name": { + "question": "Quel est le nom du magasin de vélos ?", + "render": "Ce magasin s'appelle {name}" + }, + "bike_shop-phone": { + "question": "Quel est le numéro de téléphone de {name} ?" + }, + "bike_shop-website": { + "question": "Quel est le site web de {name} ?" } }, "title": { @@ -705,18 +690,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Ce défibrillateur est en intérieur (dans un batiment)" - }, - "1": { - "then": "Ce défibrillateur est situé en extérieur" - } - }, - "question": "Ce défibrillateur est-il disposé en intérieur ?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Librement accessible" @@ -737,7 +711,7 @@ "question": "Ce défibrillateur est-il librement accessible ?", "render": "{access} accessible" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "C'est un défibrillateur manuel pour professionnel" @@ -749,7 +723,42 @@ "question": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", "render": "Il n'y a pas d'information sur le type de dispositif" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", + "render": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", + "render": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", + "render": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}" + }, + "defibrillator-description": { + "question": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", + "render": "Informations supplémentaires : {description}" + }, + "defibrillator-email": { + "question": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", + "render": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}" + }, + "defibrillator-fixme": { + "question": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", + "render": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Ce défibrillateur est en intérieur (dans un batiment)" + }, + "1": { + "then": "Ce défibrillateur est situé en extérieur" + } + }, + "question": "Ce défibrillateur est-il disposé en intérieur ?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Ce défibrillateur est au rez-de-chaussée" @@ -761,31 +770,7 @@ "question": "À quel étage est situé ce défibrillateur ?", "render": "Ce défibrillateur est à l'étage {level}" }, - "5": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", - "render": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}" - }, - "6": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", - "render": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}" - }, - "7": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", - "render": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}" - }, - "9": { - "question": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", - "render": "Numéro d'identification officiel de ce dispositif : {ref}" - }, - "10": { - "question": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", - "render": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}" - }, - "11": { - "question": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", - "render": "Numéro de téléphone pour questions sur le défibrillateur : {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "Ouvert 24/7 (jours feriés inclus)" @@ -794,11 +779,15 @@ "question": "À quels horaires ce défibrillateur est-il accessible ?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", - "render": "Informations supplémentaires : {description}" + "defibrillator-phone": { + "question": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", + "render": "Numéro de téléphone pour questions sur le défibrillateur : {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", + "render": "Numéro d'identification officiel de ce dispositif : {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Vérifié aujourd'hui !" @@ -806,10 +795,6 @@ }, "question": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", "render": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}" - }, - "15": { - "question": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", - "render": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}" } }, "title": { @@ -824,11 +809,22 @@ "name": "Eau potable", "presets": { "0": { - "title": "Eau potable" + "title": "eau potable" } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "Il est facile de remplir les bouteilles d'eau" + }, + "1": { + "then": "Les bouteilles d'eau peuvent ne pas passer" + } + }, + "question": "Est-il facile de remplir des bouteilles d'eau ?" + }, + "Still in use?": { "mappings": { "0": { "then": "Cette fontaine fonctionne" @@ -843,18 +839,7 @@ "question": "Ce point d'eau potable est-il toujours opérationnel ?", "render": "L'état opérationnel est {operational_status" }, - "2": { - "mappings": { - "0": { - "then": "Il est facile de remplir les bouteilles d'eau" - }, - "1": { - "then": "Les bouteilles d'eau peuvent ne pas passer" - } - }, - "question": "Est-il facile de remplir des bouteilles d'eau ?" - }, - "3": { + "render-closest-drinking-water": { "render": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" } }, @@ -864,21 +849,32 @@ }, "food": { "tagRenderings": { - "14": { + "friture-oil": { "mappings": { "0": { - "then": "Des collations végétariens sont disponibles" + "then": "Huile végétale" }, "1": { - "then": "Quelques snacks végétariens seulement" - }, - "2": { - "then": "Pas d'en-cas végétariens disponibles" + "then": "Graisse animale" } }, - "question": "Cette friterie est-elle équipée de snacks végétariens ?" + "question": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" }, - "15": { + "friture-take-your-container": { + "mappings": { + "0": { + "then": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets" + }, + "1": { + "then": "Apporter ses propres contenants n’est pas permis" + }, + "2": { + "then": "Il est obligatoire d’apporter ses propres contenants" + } + }, + "question": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
" + }, + "friture-vegan": { "mappings": { "0": { "then": "Des collations végétaliens sont disponibles" @@ -892,30 +888,19 @@ }, "question": "Cette friterie est-elle équipée de snacks végétaliens ?" }, - "16": { + "friture-vegetarian": { "mappings": { "0": { - "then": "Huile végétale" + "then": "Des collations végétariens sont disponibles" }, "1": { - "then": "Graisse animale" - } - }, - "question": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" - }, - "17": { - "mappings": { - "0": { - "then": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets" - }, - "1": { - "then": "Apporter ses propres contenants n’est pas permis" + "then": "Quelques snacks végétariens seulement" }, "2": { - "then": "Il est obligatoire d’apporter ses propres contenants" + "then": "Pas d'en-cas végétariens disponibles" } }, - "question": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
" + "question": "Cette friterie est-elle équipée de snacks végétariens ?" } } }, @@ -927,10 +912,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." }, - "2": { + "ghost_bike-inscription": { + "question": "Quelle est l'inscription sur ce vélo fantôme ?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Aucun nom n'est marqué sur le vélo" @@ -939,15 +928,11 @@ "question": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
", "render": "En souvenir de {name}" }, - "3": { + "ghost_bike-source": { "question": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?", "render": "
Plus d'informations sont disponibles" }, - "4": { - "question": "Quelle est l'inscription sur ce vélo fantôme ?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Quand ce vélo fantôme a-t-il été installée ?", "render": "Placé le {start_date}" } @@ -965,7 +950,7 @@ "name": "Panneaux d'informations", "presets": { "0": { - "title": "Panneau d'informations" + "title": "panneau d'informations" } }, "title": { @@ -982,16 +967,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Cette carte est basée sur OpenStreetMap" - } - }, - "question": "Sur quelles données cette carte est-elle basée ?", - "render": "Cette carte est basée sur {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "L’attribution est clairement inscrite ainsi que la licence ODBL" @@ -1010,6 +986,15 @@ } }, "question": "L’attribution à OpenStreetMap est elle-présente ?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Cette carte est basée sur OpenStreetMap" + } + }, + "question": "Sur quelles données cette carte est-elle basée ?", + "render": "Cette carte est basée sur {map_source}" } }, "title": { @@ -1018,7 +1003,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public", + "render": "{curator} est en charge de la conservation de la réserve" + }, + "Dogs?": { "mappings": { "0": { "then": "Les chiens doivent être tenus en laisse" @@ -1032,23 +1021,19 @@ }, "question": "Les chiens sont-ils autorisés dans cette réserve naturelle ?" }, - "6": { - "question": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?" - }, - "7": { - "question": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public", - "render": "{curator} est en charge de la conservation de la réserve" - }, - "8": { + "Email": { "question": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Superficie : {_surface:ha} ha" + }, + "Website": { + "question": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?" + }, + "phone": { "question": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié", "render": "{phone}" - }, - "12": { - "render": "Superficie : {_surface:ha} ha" } } }, @@ -1057,11 +1042,11 @@ "name": "Tables de pique-nique", "presets": { "0": { - "title": "Table de pique-nique" + "title": "table de pique-nique" } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "C’est une table en bois" @@ -1087,7 +1072,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Entièrement accessible aux personnes en fauteuil roulant" + }, + "1": { + "then": "Accessibilité limitée pour les personnes en fauteuil roulant" + }, + "2": { + "then": "Non accessible aux personnes en fauteuil roulant" + } + }, + "question": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessible au public" + }, + "1": { + "then": "Accessible au public" + }, + "2": { + "then": "Réservée aux clients" + }, + "3": { + "then": "Réservée aux élèves de l’école" + }, + "4": { + "then": "Non accessible" + } + }, + "question": "L’aire de jeu est-elle accessible au public ?" + }, + "playground-email": { + "question": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "L’aire de jeu est éclairée de nuit" + }, + "1": { + "then": "L’aire de jeu n’est pas éclairée de nuit" + } + }, + "question": "Ce terrain de jeux est-il éclairé la nuit ?" + }, + "playground-max_age": { + "question": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?", + "render": "Accessible aux enfants de {max_age} au maximum" + }, + "playground-min_age": { + "question": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", + "render": "Accessible aux enfants de plus de {min_age} ans" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Accessible du lever au coucher du soleil" + }, + "1": { + "then": "Toujours accessible" + }, + "2": { + "then": "Toujours accessible" + } + }, + "question": "Quand ce terrain de jeux est-il accessible ?" + }, + "playground-operator": { + "question": "Qui est en charge de l’exploitation de l’aire de jeu ?", + "render": "Exploité par {operator}" + }, + "playground-phone": { + "question": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "La surface est en gazon" @@ -1116,85 +1180,6 @@ }, "question": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale", "render": "La surface est en {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "L’aire de jeu est éclairée de nuit" - }, - "1": { - "then": "L’aire de jeu n’est pas éclairée de nuit" - } - }, - "question": "Ce terrain de jeux est-il éclairé la nuit ?" - }, - "3": { - "question": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", - "render": "Accessible aux enfants de plus de {min_age} ans" - }, - "4": { - "question": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?", - "render": "Accessible aux enfants de {max_age} au maximum" - }, - "5": { - "question": "Qui est en charge de l’exploitation de l’aire de jeu ?", - "render": "Exploité par {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessible au public" - }, - "1": { - "then": "Accessible au public" - }, - "2": { - "then": "Réservée aux clients" - }, - "3": { - "then": "Réservée aux élèves de l’école" - }, - "4": { - "then": "Non accessible" - } - }, - "question": "L’aire de jeu est-elle accessible au public ?" - }, - "7": { - "question": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", - "render": "{email}" - }, - "8": { - "question": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Entièrement accessible aux personnes en fauteuil roulant" - }, - "1": { - "then": "Accessibilité limitée pour les personnes en fauteuil roulant" - }, - "2": { - "then": "Non accessible aux personnes en fauteuil roulant" - } - }, - "question": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?" - }, - "10": { - "mappings": { - "0": { - "then": "Accessible du lever au coucher du soleil" - }, - "1": { - "then": "Toujours accessible" - }, - "2": { - "then": "Toujours accessible" - } - }, - "question": "Quand ce terrain de jeux est-il accessible ?" } }, "title": { @@ -1215,20 +1200,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Cette microbibliothèque n'a pas de nom" - } - }, - "question": "Quel est le nom de cette microbibliothèque ?", - "render": "Le nom de cette microbibliothèque est {name}" - }, - "3": { - "question": "Combien de livres peuvent entrer dans cette microbibliothèque ?", - "render": "{capacity} livres peuvent entrer dans cette microbibliothèque" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Livres pour enfants" @@ -1242,7 +1214,18 @@ }, "question": "Quel type de livres peut-on dans cette microbibliothèque ?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Accèssible au public" + }, + "1": { + "then": "Accèssible aux clients" + } + }, + "question": "Cette microbibliothèque est-elle librement accèssible ?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Cette microbibliothèque est en intérieur" @@ -1256,22 +1239,7 @@ }, "question": "Cette microbiliothèque est-elle en extérieur ?" }, - "6": { - "mappings": { - "0": { - "then": "Accèssible au public" - }, - "1": { - "then": "Accèssible aux clients" - } - }, - "question": "Cette microbibliothèque est-elle librement accèssible ?" - }, - "7": { - "question": "Qui entretien cette microbibliothèque ?", - "render": "Entretenue par {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Fait partie du réseau Little Free Library" @@ -1283,7 +1251,24 @@ "question": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", "render": "Cette microbibliothèque fait partie du groupe {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Combien de livres peuvent entrer dans cette microbibliothèque ?", + "render": "{capacity} livres peuvent entrer dans cette microbibliothèque" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Cette microbibliothèque n'a pas de nom" + } + }, + "question": "Quel est le nom de cette microbibliothèque ?", + "render": "Le nom de cette microbibliothèque est {name}" + }, + "public_bookcase-operator": { + "question": "Qui entretien cette microbibliothèque ?", + "render": "Entretenue par {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe" @@ -1292,11 +1277,11 @@ "question": "Quelle est le numéro de référence de cette microbibliothèque ?", "render": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Quand a été installée cette microbibliothèque ?", "render": "Installée le {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", "render": "Plus d'infos sur le site web" } @@ -1312,7 +1297,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "La surface est en herbe" @@ -1355,7 +1340,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Accessible au public" + }, + "1": { + "then": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)" + }, + "2": { + "then": "Accessible uniquement aux membres du club" + }, + "3": { + "then": "Privé - Pas accessible au public" + } + }, + "question": "Est-ce que ce terrain de sport est accessible au public ?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Il est obligatoire de réserver pour utiliser ce terrain de sport" + }, + "1": { + "then": "Il est recommendé de réserver pour utiliser ce terrain de sport" + }, + "2": { + "then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport" + }, + "3": { + "then": "On ne peut pas réserver" + } + }, + "question": "Doit-on réserver pour utiliser ce terrain de sport ?" + }, + "sport_pitch-email": { + "question": "Quelle est l'adresse courriel du gérant ?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Accessible en permanence" + } + }, + "question": "Quand ce terrain est-il accessible ?" + }, + "sport_pitch-phone": { + "question": "Quel est le numéro de téléphone du gérant ?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Ici, on joue au basketball" @@ -1379,7 +1412,7 @@ "question": "À quel sport peut-on jouer ici ?", "render": "Ici on joue au {sport}" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "La surface est de l'herbe" @@ -1399,54 +1432,6 @@ }, "question": "De quelle surface est fait ce terrain de sport ?", "render": "La surface est {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Accessible au public" - }, - "1": { - "then": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)" - }, - "2": { - "then": "Accessible uniquement aux membres du club" - }, - "3": { - "then": "Privé - Pas accessible au public" - } - }, - "question": "Est-ce que ce terrain de sport est accessible au public ?" - }, - "4": { - "mappings": { - "0": { - "then": "Il est obligatoire de réserver pour utiliser ce terrain de sport" - }, - "1": { - "then": "Il est recommendé de réserver pour utiliser ce terrain de sport" - }, - "2": { - "then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport" - }, - "3": { - "then": "On ne peut pas réserver" - } - }, - "question": "Doit-on réserver pour utiliser ce terrain de sport ?" - }, - "5": { - "question": "Quel est le numéro de téléphone du gérant ?" - }, - "6": { - "question": "Quelle est l'adresse courriel du gérant ?" - }, - "7": { - "mappings": { - "1": { - "then": "Accessible en permanence" - } - }, - "question": "Quand ce terrain est-il accessible ?" } }, "title": { @@ -1456,7 +1441,7 @@ "surveillance_camera": { "name": "Caméras de surveillance", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Une caméra fixe (non mobile)" @@ -1470,34 +1455,7 @@ }, "question": "Quel genre de caméra est-ce ?" }, - "2": { - "mappings": { - "0": { - "then": "Filme dans une direction {direction}" - } - }, - "question": "Dans quelle direction géographique cette caméra filme-t-elle ?", - "render": "Filme dans une direction {camera:direction}" - }, - "3": { - "question": "Qui exploite ce système de vidéosurveillance ?", - "render": "Exploité par {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…" - }, - "1": { - "then": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)" - }, - "2": { - "then": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…" - } - }, - "question": "Quel genre de surveillance est cette caméra" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Cette caméra est située à l'intérieur" @@ -1511,11 +1469,29 @@ }, "question": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?" }, - "6": { + "Level": { "question": "À quel niveau se trouve cette caméra ?", "render": "Situé au niveau {level}" }, - "7": { + "Operator": { + "question": "Qui exploite ce système de vidéosurveillance ?", + "render": "Exploité par {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…" + }, + "1": { + "then": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)" + }, + "2": { + "then": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…" + } + }, + "question": "Quel genre de surveillance est cette caméra" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Surveille un parking" @@ -1539,7 +1515,7 @@ "question": "Qu'est-ce qui est surveillé ici ?", "render": " Surveille un(e) {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Cette caméra est placée contre un mur" @@ -1553,6 +1529,15 @@ }, "question": "Comment cette caméra est-elle placée ?", "render": "Méthode de montage : {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Filme dans une direction {direction}" + } + }, + "question": "Dans quelle direction géographique cette caméra filme-t-elle ?", + "render": "Filme dans une direction {camera:direction}" } }, "title": { @@ -1564,15 +1549,15 @@ "presets": { "0": { "description": "Des toilettes", - "title": "Toilettes" + "title": "toilettes" }, "1": { "description": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", - "title": "Toilettes accessible aux personnes à mobilité réduite" + "title": "toilettes accessible aux personnes à mobilité réduite" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Accès publique" @@ -1593,61 +1578,7 @@ "question": "Ces toilettes sont-elles accessibles au public ?", "render": "L'accès est {access}" }, - "2": { - "mappings": { - "0": { - "then": "Toilettes payantes" - }, - "1": { - "then": "Toilettes gratuites" - } - }, - "question": "Ces toilettes sont-elles payantes ?" - }, - "3": { - "question": "Quel est le prix d'accès de ces toilettes ?", - "render": "Le prix est {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Il y a des toilettes réservées pour les personnes à mobilité réduite" - }, - "1": { - "then": "Non accessible aux personnes à mobilité réduite" - } - }, - "question": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?" - }, - "5": { - "mappings": { - "0": { - "then": "Il y a uniquement des sièges de toilettes" - }, - "1": { - "then": "Il y a uniquement des urinoirs" - }, - "2": { - "then": "Il y a uniquement des toilettes turques" - }, - "3": { - "then": "Il y a des sièges de toilettes et des urinoirs" - } - }, - "question": "De quel type sont ces toilettes ?" - }, - "6": { - "mappings": { - "0": { - "then": "Une table à langer est disponible" - }, - "1": { - "then": "Aucune table à langer" - } - }, - "question": "Ces toilettes disposent-elles d'une table à langer ?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "La table à langer est dans les toilettes pour femmes. " @@ -1664,6 +1595,60 @@ }, "question": "Où se situe la table à langer ?", "render": "Emplacement de la table à langer : {changing_table:location}" + }, + "toilet-charge": { + "question": "Quel est le prix d'accès de ces toilettes ?", + "render": "Le prix est {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Une table à langer est disponible" + }, + "1": { + "then": "Aucune table à langer" + } + }, + "question": "Ces toilettes disposent-elles d'une table à langer ?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Toilettes payantes" + }, + "1": { + "then": "Toilettes gratuites" + } + }, + "question": "Ces toilettes sont-elles payantes ?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Il y a uniquement des sièges de toilettes" + }, + "1": { + "then": "Il y a uniquement des urinoirs" + }, + "2": { + "then": "Il y a uniquement des toilettes turques" + }, + "3": { + "then": "Il y a des sièges de toilettes et des urinoirs" + } + }, + "question": "De quel type sont ces toilettes ?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Il y a des toilettes réservées pour les personnes à mobilité réduite" + }, + "1": { + "then": "Non accessible aux personnes à mobilité réduite" + } + }, + "question": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?" } }, "title": { @@ -1687,29 +1672,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Hauteur : {height} m" - } - }, - "render": "Hauteur : {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Feuillu" + "then": "Caduc : l’arbre perd son feuillage une partie de l’année." }, "1": { - "then": "\"\"/ Résineux" - }, - "2": { - "then": "\"\"/ Sans feuilles (Permanent)" + "then": "À feuilles persistantes." } }, - "question": "Cet arbre est-il un feuillu ou un résineux ?" + "question": "L’arbre est-il à feuillage persistant ou caduc ?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." @@ -1738,27 +1712,15 @@ }, "question": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Caduc : l’arbre perd son feuillage une partie de l’année." - }, - "1": { - "then": "À feuilles persistantes." + "then": "Hauteur : {height} m" } }, - "question": "L’arbre est-il à feuillage persistant ou caduc ?" + "render": "Hauteur : {height}" }, - "5": { - "mappings": { - "0": { - "then": "L'arbre n'a pas de nom." - } - }, - "question": "L'arbre a-t-il un nom ?", - "render": "Nom : {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" @@ -1778,11 +1740,34 @@ }, "question": "Cet arbre est-il inscrit au patrimoine ?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Feuillu" + }, + "1": { + "then": "\"\"/ Résineux" + }, + "2": { + "then": "\"\"/ Sans feuilles (Permanent)" + } + }, + "question": "Cet arbre est-il un feuillu ou un résineux ?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "L'arbre n'a pas de nom." + } + }, + "question": "L'arbre a-t-il un nom ?", + "render": "Nom : {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Quel est son identifiant donné par Onroerend Erfgoed ?", "render": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Quel est l'identifiant Wikidata de cet arbre ?", "render": "\"\"/ Wikidata : {wikidata}" } @@ -1805,7 +1790,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Voulez-vous ajouter une description ?" } }, diff --git a/langs/layers/gl.json b/langs/layers/gl.json index 5a6d58c6d..aa261176f 100644 --- a/langs/layers/gl.json +++ b/langs/layers/gl.json @@ -7,11 +7,7 @@ } }, "tagRenderings": { - "1": { - "question": "Cal é o nome deste café de ciclistas?", - "render": "Este café de ciclistas chámase {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Este café de ciclistas ofrece unha bomba de ar" @@ -22,18 +18,17 @@ }, "question": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?" }, - "3": { - "mappings": { - "0": { - "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" - }, - "1": { - "then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta" - } - }, - "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + "bike_cafe-email": { + "question": "Cal é o enderezo de correo electrónico de {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Cal é o nome deste café de ciclistas?", + "render": "Este café de ciclistas chámase {name}" + }, + "bike_cafe-phone": { + "question": "Cal é o número de teléfono de {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Este café de ciclistas arranxa bicicletas" @@ -44,14 +39,19 @@ }, "question": "Este café de ciclistas arranxa bicicletas?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" + }, + "1": { + "then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta" + } + }, + "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + }, + "bike_cafe-website": { "question": "Cal é a páxina web de {name}?" - }, - "6": { - "question": "Cal é o número de teléfono de {name}?" - }, - "7": { - "question": "Cal é o enderezo de correo electrónico de {name}?" } }, "title": { @@ -71,7 +71,7 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "mappings": { "0": { "then": "De roda (Stands) " @@ -95,22 +95,15 @@ "question": "Que tipo de aparcadoiro de bicicletas é?", "render": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}" }, - "3": { - "mappings": { - "0": { - "then": "Este aparcadoiro está cuberto (ten un teito)" - }, - "1": { - "then": "Este aparcadoiro non está cuberto" - } - }, - "question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores." - }, - "4": { + "Capacity": { "question": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", "render": "Lugar para {capacity} bicicletas" }, - "6": { + "Cargo bike capacity?": { + "question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", + "render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga" + }, + "Cargo bike spaces?": { "mappings": { "0": { "then": "Este aparcadoiro ten espazo para bicicletas de carga." @@ -124,9 +117,16 @@ }, "question": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?" }, - "7": { - "question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", - "render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga" + "Is covered?": { + "mappings": { + "0": { + "then": "Este aparcadoiro está cuberto (ten un teito)" + }, + "1": { + "then": "Este aparcadoiro non está cuberto" + } + }, + "question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores." } }, "title": { @@ -147,7 +147,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "A bomba de ar está estragada" + }, + "1": { + "then": "A bomba de ar está operativa" + } + }, + "question": "Segue a funcionar a bomba de ar?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Só hai unha bomba de ar presente" @@ -161,7 +172,7 @@ }, "question": "Que servizos están dispoñíbeis nesta estación de bicicletas?" }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Hai unha ferramenta para a cadea" @@ -172,7 +183,7 @@ }, "question": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Hai un guindastre ou soporte" @@ -183,18 +194,32 @@ }, "question": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "A bomba de ar está estragada" + "then": "Bomba de ar manual" }, "1": { - "then": "A bomba de ar está operativa" + "then": "Bomba de ar eléctrica" } }, - "question": "Segue a funcionar a bomba de ar?" + "question": "Esta é unha bomba de ar eléctrica?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Hai manómetro" + }, + "1": { + "then": "Non hai manómetro" + }, + "2": { + "then": "Hai manómetro pero está estragado" + } + }, + "question": "Ten a bomba de ar un indicador de presión ou un manómetro?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (tamén coñecido como Presta)" @@ -208,31 +233,6 @@ }, "question": "Que válvulas son compatíbeis?", "render": "Esta bomba de ar admite as seguintes válvulas: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Bomba de ar manual" - }, - "1": { - "then": "Bomba de ar eléctrica" - } - }, - "question": "Esta é unha bomba de ar eléctrica?" - }, - "12": { - "mappings": { - "0": { - "then": "Hai manómetro" - }, - "1": { - "then": "Non hai manómetro" - }, - "2": { - "then": "Hai manómetro pero está estragado" - } - }, - "question": "Ten a bomba de ar un indicador de presión ou un manómetro?" } }, "title": { @@ -264,31 +264,29 @@ } }, "tagRenderings": { - "2": { - "question": "Cal é o nome desta tenda de bicicletas?", - "render": "Esta tenda de bicicletas chámase {name}" - }, - "3": { - "question": "Cal é a páxina web de {name}?" - }, - "4": { - "question": "Cal é o número de teléfono de {name}?" - }, - "5": { - "question": "Cal é o enderezo de correo electrónico de {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Esta tenda vende bicicletas" + "then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa" }, "1": { - "then": "Esta tenda non vende bicicletas" + "then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa" } }, - "question": "Esta tenda vende bicicletas?" + "question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?" }, - "10": { + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Esta tenda aluga bicicletas" + }, + "1": { + "then": "Esta tenda non aluga bicicletas" + } + }, + "question": "Esta tenda aluga bicicletas?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Esta tenda arranxa bicicletas" @@ -305,18 +303,7 @@ }, "question": "Esta tenda arranxa bicicletas?" }, - "11": { - "mappings": { - "0": { - "then": "Esta tenda aluga bicicletas" - }, - "1": { - "then": "Esta tenda non aluga bicicletas" - } - }, - "question": "Esta tenda aluga bicicletas?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Esta tenda vende bicicletas de segunda man" @@ -330,18 +317,18 @@ }, "question": "Esta tenda vende bicicletas de segunda man?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa" + "then": "Esta tenda vende bicicletas" }, "1": { - "then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa" + "then": "Esta tenda non vende bicicletas" } }, - "question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?" + "question": "Esta tenda vende bicicletas?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" @@ -351,6 +338,19 @@ } }, "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + }, + "bike_shop-email": { + "question": "Cal é o enderezo de correo electrónico de {name}?" + }, + "bike_shop-name": { + "question": "Cal é o nome desta tenda de bicicletas?", + "render": "Esta tenda de bicicletas chámase {name}" + }, + "bike_shop-phone": { + "question": "Cal é o número de teléfono de {name}?" + }, + "bike_shop-website": { + "question": "Cal é a páxina web de {name}?" } }, "title": { @@ -372,7 +372,7 @@ "name": "Auga potábel", "presets": { "0": { - "title": "Auga potábel" + "title": "auga potábel" } }, "title": { diff --git a/langs/layers/hu.json b/langs/layers/hu.json index 4ffbf2671..5fb6aa09b 100644 --- a/langs/layers/hu.json +++ b/langs/layers/hu.json @@ -1,13 +1,8 @@ { "bench": { "name": "Padok", - "presets": { - "0": { - "description": "Pad hozzáadása" - } - }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Háttámla: Igen" @@ -19,39 +14,7 @@ "question": "Van háttámlája ennek a padnak?", "render": "Háttámla" }, - "2": { - "question": "Hány ülőhely van ezen a padon?", - "render": "{seats} ülőhely" - }, - "3": { - "mappings": { - "0": { - "then": "Anyag: fa" - }, - "1": { - "then": "Anyag: fém" - }, - "2": { - "then": "Anyag: kő" - }, - "3": { - "then": "Anyag: beton" - }, - "4": { - "then": "Anyag: műanyag" - }, - "5": { - "then": "Anyag: acél" - } - }, - "question": "Miből van a pad (ülő része)?", - "render": "Anyag: {material}" - }, - "4": { - "question": "Milyen irányba néz a pad?", - "render": "A pad {direction}° felé néz." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Szín: barna" @@ -80,6 +43,38 @@ }, "question": "Milyen színű a pad?", "render": "Szín: {colour}" + }, + "bench-direction": { + "question": "Milyen irányba néz a pad?", + "render": "A pad {direction}° felé néz." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Anyag: fa" + }, + "1": { + "then": "Anyag: fém" + }, + "2": { + "then": "Anyag: kő" + }, + "3": { + "then": "Anyag: beton" + }, + "4": { + "then": "Anyag: műanyag" + }, + "5": { + "then": "Anyag: acél" + } + }, + "question": "Miből van a pad (ülő része)?", + "render": "Anyag: {material}" + }, + "bench-seats": { + "question": "Hány ülőhely van ezen a padon?", + "render": "{seats} ülőhely" } }, "title": { @@ -89,7 +84,7 @@ "bench_at_pt": { "name": "Padok megállókban", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -108,7 +103,15 @@ "bicycle_library": { "description": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", "tagRenderings": { - "6": { + "bicycle-library-target-group": { + "mappings": { + "0": { + "then": "" + } + }, + "question": "Ki kölcsönözhet itt kerékpárt?" + }, + "bicycle_library-charge": { "mappings": { "0": { "then": "A kerékpárkölcsönzés ingyenes" @@ -116,20 +119,12 @@ }, "question": "Mennyibe kerül egy kerékpár kölcsönzése?", "render": "Egy kerékpár kölcsönzése {charge}" - }, - "7": { - "mappings": { - "0": { - "then": "" - } - }, - "question": "Ki kölcsönözhet itt kerékpárt?" } } }, "bicycle_tube_vending_machine": { "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Az automata működik" @@ -152,7 +147,7 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "mappings": { "0": { "then": "\"U\" " @@ -170,7 +165,18 @@ "question": "Milyen típusú ez a kerékpáros parkoló?", "render": "Ez egy {bicycle_parking} típusú kerékpáros parkoló" }, - "2": { + "Is covered?": { + "mappings": { + "0": { + "then": "A parkoló fedett" + }, + "1": { + "then": "A parkoló nem fedett" + } + }, + "question": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)" + }, + "Underground?": { "mappings": { "2": { "then": "Felszíni parkoló" @@ -182,17 +188,6 @@ "then": "Tetőparkoló" } } - }, - "3": { - "mappings": { - "0": { - "then": "A parkoló fedett" - }, - "1": { - "then": "A parkoló nem fedett" - } - }, - "question": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)" } }, "title": { diff --git a/langs/layers/id.json b/langs/layers/id.json index d6990fce5..54f3e27c2 100644 --- a/langs/layers/id.json +++ b/langs/layers/id.json @@ -3,11 +3,11 @@ "name": "Bangku", "presets": { "0": { - "title": "Bangku" + "title": "bangku" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Sandaran: Ya" @@ -19,11 +19,11 @@ "question": "Apakah bangku ini memiliki sandaran?", "render": "Sandaran" }, - "2": { - "render": "{seats} kursi" - }, - "5": { + "bench-colour": { "render": "Warna: {colour}" + }, + "bench-seats": { + "render": "{seats} kursi" } }, "title": { @@ -32,7 +32,7 @@ }, "bench_at_pt": { "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -42,21 +42,21 @@ }, "bike_parking": { "tagRenderings": { - "5": { + "Access": { "render": "{access}" } } }, "bike_shop": { "tagRenderings": { - "3": { + "bike_shop-website": { "question": "URL {name} apa?" } } }, "defibrillator": { "tagRenderings": { - "13": { + "defibrillator-description": { "render": "Informasi tambahan: {description}" } } @@ -65,7 +65,7 @@ "name": "Air minum", "presets": { "0": { - "title": "Air minum" + "title": "air minum" } }, "title": { @@ -74,30 +74,30 @@ }, "ghost_bike": { "tagRenderings": { - "3": { - "render": "Informasi lanjut tersedia" - }, - "4": { + "ghost_bike-inscription": { "render": "{inscription}" + }, + "ghost_bike-source": { + "render": "Informasi lanjut tersedia" } } }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } }, "playground": { "tagRenderings": { - "7": { + "playground-email": { "render": "{email}" }, - "8": { + "playground-phone": { "render": "{phone}" } } @@ -109,7 +109,7 @@ } }, "tagRenderings": { - "5": { + "tree_node-name": { "render": "Nama: {name}" } }, @@ -129,7 +129,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Apakah Anda ingin menambahkan deskripsi?" } }, diff --git a/langs/layers/it.json b/langs/layers/it.json index af1edc7e4..b8585841f 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -3,12 +3,11 @@ "name": "Panchine", "presets": { "0": { - "description": "Aggiungi una nuova panchina", - "title": "Panchina" + "title": "panchina" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Schienale: Sì" @@ -20,39 +19,7 @@ "question": "Questa panchina ha lo schienale?", "render": "Schienale" }, - "2": { - "question": "Quanti posti ha questa panchina?", - "render": "{seats} posti" - }, - "3": { - "mappings": { - "0": { - "then": "Materiale: legno" - }, - "1": { - "then": "Materiale: metallo" - }, - "2": { - "then": "Materiale: pietra" - }, - "3": { - "then": "Materiale: cemento" - }, - "4": { - "then": "Materiale: plastica" - }, - "5": { - "then": "Materiale: acciaio" - } - }, - "question": "Di che materiale è fatta questa panchina?", - "render": "Materiale: {material}" - }, - "4": { - "question": "In che direzione si guarda quando si è seduti su questa panchina?", - "render": "Quando si è seduti su questa panchina, si guarda verso {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Colore: marrone" @@ -82,7 +49,39 @@ "question": "Di che colore è questa panchina?", "render": "Colore: {colour}" }, - "6": { + "bench-direction": { + "question": "In che direzione si guarda quando si è seduti su questa panchina?", + "render": "Quando si è seduti su questa panchina, si guarda verso {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiale: legno" + }, + "1": { + "then": "Materiale: metallo" + }, + "2": { + "then": "Materiale: pietra" + }, + "3": { + "then": "Materiale: cemento" + }, + "4": { + "then": "Materiale: plastica" + }, + "5": { + "then": "Materiale: acciaio" + } + }, + "question": "Di che materiale è fatta questa panchina?", + "render": "Materiale: {material}" + }, + "bench-seats": { + "question": "Quanti posti ha questa panchina?", + "render": "{seats} posti" + }, + "bench-survey:date": { "question": "Quando è stata verificata l’ultima volta questa panchina?", "render": "Questa panchina è stata controllata l’ultima volta in data {survey:date}" } @@ -94,11 +93,11 @@ "bench_at_pt": { "name": "Panchine alle fermate del trasporto pubblico", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Panca in piedi" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +122,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual è il nome di questo “bici in prestito”?", - "render": "Il “bici in prestito” è chiamato {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Il prestito di una bicicletta è gratuito" - }, - "1": { - "then": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia" - } - }, - "question": "Quanto costa il prestito di una bicicletta?", - "render": "Il prestito di una bicicletta costa {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Sono disponibili biciclette per bambini" @@ -152,6 +135,22 @@ } }, "question": "Chi può prendere in prestito le biciclette qua?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Il prestito di una bicicletta è gratuito" + }, + "1": { + "then": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia" + } + }, + "question": "Quanto costa il prestito di una bicicletta?", + "render": "Il prestito di una bicicletta costa {charge}" + }, + "bicycle_library-name": { + "question": "Qual è il nome di questo “bici in prestito”?", + "render": "Il “bici in prestito” è chiamato {name}" } }, "title": { @@ -166,7 +165,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Il distributore automatico funziona" @@ -194,11 +193,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual è il nome di questo caffè in bici?", - "render": "Questo caffè in bici è chiamato {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile" @@ -209,18 +204,20 @@ }, "question": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?" }, - "3": { - "mappings": { - "0": { - "then": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te" - }, - "1": { - "then": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te" - } - }, - "question": "Ci sono degli strumenti per riparare la propria bicicletta?" + "bike_cafe-email": { + "question": "Qual è l’indirizzo email di {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Qual è il nome di questo caffè in bici?", + "render": "Questo caffè in bici è chiamato {name}" + }, + "bike_cafe-opening_hours": { + "question": "Quando è aperto questo caffè in bici?" + }, + "bike_cafe-phone": { + "question": "Qual è il numero di telefono di {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Questo caffè in bici ripara le bici" @@ -231,17 +228,19 @@ }, "question": "Questo caffè in bici ripara le bici?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te" + }, + "1": { + "then": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te" + } + }, + "question": "Ci sono degli strumenti per riparare la propria bicicletta?" + }, + "bike_cafe-website": { "question": "Qual è il sito web di {name}?" - }, - "6": { - "question": "Qual è il numero di telefono di {name}?" - }, - "7": { - "question": "Qual è l’indirizzo email di {name}?" - }, - "8": { - "question": "Quando è aperto questo caffè in bici?" } }, "title": { @@ -269,20 +268,6 @@ "render": "Servizio lavaggio bici" } }, - "bike_monitoring_station": { - "name": "Stazioni di monitoraggio", - "title": { - "mappings": { - "0": { - "then": "Contabiciclette {name}" - }, - "1": { - "then": "Contabiciclette {ref}" - } - }, - "render": "Contabiciclette" - } - }, "bike_parking": { "name": "Parcheggio bici", "presets": { @@ -291,7 +276,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Accessibile pubblicamente" + }, + "1": { + "then": "Accesso destinato principalmente ai visitatori di un’attività" + }, + "2": { + "then": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione" + } + }, + "question": "Chi può usare questo parcheggio bici?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Archetti " @@ -321,7 +321,40 @@ "question": "Di che tipo di parcheggio bici si tratta?", "render": "È un parcheggio bici del tipo: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", + "render": "Posti per {capacity} bici" + }, + "Cargo bike capacity?": { + "question": "Quante bici da trasporto entrano in questo parcheggio per bici?", + "render": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Questo parcheggio ha posto per bici da trasporto" + }, + "1": { + "then": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto." + }, + "2": { + "then": "Il parcheggio delle bici da trasporto è proibito" + } + }, + "question": "Questo parcheggio dispone di posti specifici per le bici da trasporto?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "È un parcheggio coperto (ha un tetto)" + }, + "1": { + "then": "Non è un parcheggio coperto" + } + }, + "question": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno." + }, + "Underground?": { "mappings": { "0": { "then": "Parcheggio sotterraneo" @@ -340,54 +373,6 @@ } }, "question": "Qual è la posizione relativa di questo parcheggio bici?" - }, - "3": { - "mappings": { - "0": { - "then": "È un parcheggio coperto (ha un tetto)" - }, - "1": { - "then": "Non è un parcheggio coperto" - } - }, - "question": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno." - }, - "4": { - "question": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", - "render": "Posti per {capacity} bici" - }, - "5": { - "mappings": { - "0": { - "then": "Accessibile pubblicamente" - }, - "1": { - "then": "Accesso destinato principalmente ai visitatori di un’attività" - }, - "2": { - "then": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione" - } - }, - "question": "Chi può usare questo parcheggio bici?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Questo parcheggio ha posto per bici da trasporto" - }, - "1": { - "then": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto." - }, - "2": { - "then": "Il parcheggio delle bici da trasporto è proibito" - } - }, - "question": "Questo parcheggio dispone di posti specifici per le bici da trasporto?" - }, - "7": { - "question": "Quante bici da trasporto entrano in questo parcheggio per bici?", - "render": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto" } }, "title": { @@ -413,7 +398,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "La pompa per bici è guasta" + }, + "1": { + "then": "La pompa per bici funziona" + } + }, + "question": "La pompa per bici è sempre funzionante?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "C’è solamente una pompa presente" @@ -427,22 +423,7 @@ }, "question": "Quali servizi sono disponibili in questa stazione per bici?" }, - "2": { - "question": "Chi gestisce questa pompa per bici?", - "render": "Manutenuta da {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Sempre aperto" - }, - "1": { - "then": "Sempre aperto" - } - }, - "question": "Quando è aperto questo punto riparazione bici?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "È presente un utensile per riparare la catena" @@ -453,7 +434,7 @@ }, "question": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "C’è un gancio o un supporto" @@ -464,18 +445,47 @@ }, "question": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "La pompa per bici è guasta" + "then": "Pompa manuale" }, "1": { - "then": "La pompa per bici funziona" + "then": "Pompa elettrica" } }, - "question": "La pompa per bici è sempre funzionante?" + "question": "Questa pompa per bici è elettrica?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "C’è un manometro" + }, + "1": { + "then": "Non c’è un manometro" + }, + "2": { + "then": "C’è un manometro ma è rotto" + } + }, + "question": "Questa pompa ha l’indicatore della pressione o il manometro?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Sempre aperto" + }, + "1": { + "then": "Sempre aperto" + } + }, + "question": "Quando è aperto questo punto riparazione bici?" + }, + "bike_repair_station-operator": { + "question": "Chi gestisce questa pompa per bici?", + "render": "Manutenuta da {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (detta anche Presta)" @@ -489,31 +499,6 @@ }, "question": "Quali valvole sono supportate?", "render": "Questa pompa è compatibile con le seguenti valvole: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Pompa manuale" - }, - "1": { - "then": "Pompa elettrica" - } - }, - "question": "Questa pompa per bici è elettrica?" - }, - "12": { - "mappings": { - "0": { - "then": "C’è un manometro" - }, - "1": { - "then": "Non c’è un manometro" - }, - "2": { - "then": "C’è un manometro ma è rotto" - } - }, - "question": "Questa pompa ha l’indicatore della pressione o il manometro?" } }, "title": { @@ -546,34 +531,46 @@ } }, "tagRenderings": { - "1": { - "render": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette" - }, - "2": { - "question": "Qual è il nome di questo negozio di biciclette?", - "render": "Questo negozio di biciclette è chiamato {name}" - }, - "3": { - "question": "Qual è il sito web di {name}?" - }, - "4": { - "question": "Qual è il numero di telefono di {name}?" - }, - "5": { - "question": "Qual è l’indirizzo email di {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Questo negozio vende bici" + "then": "Questo negozio offre l’uso pubblico di una pompa per bici" }, "1": { - "then": "Questo negozio non vende bici" + "then": "Questo negozio non offre l’uso pubblico di una pompa per bici" + }, + "2": { + "then": "C’è una pompa per bici, è mostrata come punto separato " } }, - "question": "Questo negozio vende bici?" + "question": "Questo negozio offre l’uso a chiunque di una pompa per bici?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Questo negozio lava le biciclette" + }, + "1": { + "then": "Questo negozio ha una struttura dove è possibile pulire la propria bici" + }, + "2": { + "then": "Questo negozio non offre la pulizia della bicicletta" + } + }, + "question": "Vengono lavate le bici qua?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Questo negozio noleggia le bici" + }, + "1": { + "then": "Questo negozio non noleggia le bici" + } + }, + "question": "Questo negozio noleggia le bici?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Questo negozio ripara bici" @@ -590,18 +587,7 @@ }, "question": "Questo negozio ripara bici?" }, - "11": { - "mappings": { - "0": { - "then": "Questo negozio noleggia le bici" - }, - "1": { - "then": "Questo negozio non noleggia le bici" - } - }, - "question": "Questo negozio noleggia le bici?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Questo negozio vende bici usate" @@ -615,21 +601,18 @@ }, "question": "Questo negozio vende bici usate?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Questo negozio offre l’uso pubblico di una pompa per bici" + "then": "Questo negozio vende bici" }, "1": { - "then": "Questo negozio non offre l’uso pubblico di una pompa per bici" - }, - "2": { - "then": "C’è una pompa per bici, è mostrata come punto separato " + "then": "Questo negozio non vende bici" } }, - "question": "Questo negozio offre l’uso a chiunque di una pompa per bici?" + "question": "Questo negozio vende bici?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" @@ -643,19 +626,21 @@ }, "question": "Sono presenti degli attrezzi per riparare la propria bici?" }, - "15": { - "mappings": { - "0": { - "then": "Questo negozio lava le biciclette" - }, - "1": { - "then": "Questo negozio ha una struttura dove è possibile pulire la propria bici" - }, - "2": { - "then": "Questo negozio non offre la pulizia della bicicletta" - } - }, - "question": "Vengono lavate le bici qua?" + "bike_shop-email": { + "question": "Qual è l’indirizzo email di {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette" + }, + "bike_shop-name": { + "question": "Qual è il nome di questo negozio di biciclette?", + "render": "Questo negozio di biciclette è chiamato {name}" + }, + "bike_shop-phone": { + "question": "Qual è il numero di telefono di {name}?" + }, + "bike_shop-website": { + "question": "Qual è il sito web di {name}?" } }, "title": { @@ -694,12 +679,12 @@ "description": "Una stazione di ricarica", "name": "Stazioni di ricarica", "tagRenderings": { - "41": { - "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" - }, - "42": { + "Auth phone": { "question": "A quale rete appartiene questa stazione di ricarica?", "render": "{network}" + }, + "Authentication": { + "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" } }, "title": { @@ -721,18 +706,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Questo defibrillatore si trova all’interno" - }, - "1": { - "then": "Questo defibrillatore si trova all’esterno" - } - }, - "question": "Questo defibrillatore si trova all’interno?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Pubblicamente accessibile" @@ -753,7 +727,7 @@ "question": "Questo defibrillatore è liberamente accessibile?", "render": "Accesso è {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Questo è un defibrillatore manuale per professionisti" @@ -765,7 +739,42 @@ "question": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?", "render": "Non vi sono informazioni riguardanti il tipo di questo dispositivo" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)", + "render": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Indica più precisamente dove si trova il defibrillatore (in inglese)", + "render": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Indica più precisamente dove si trova il defibrillatore (in francese)", + "render": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", + "render": "Informazioni supplementari: {description}" + }, + "defibrillator-email": { + "question": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", + "render": "Indirizzo email per le domande su questo defibrillatore:{email}" + }, + "defibrillator-fixme": { + "question": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", + "render": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Questo defibrillatore si trova all’interno" + }, + "1": { + "then": "Questo defibrillatore si trova all’esterno" + } + }, + "question": "Questo defibrillatore si trova all’interno?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Questo defibrillatore è al pian terreno" @@ -777,31 +786,7 @@ "question": "A che piano si trova questo defibrillatore?", "render": "Questo defibrillatore è al piano {level}" }, - "5": { - "question": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)", - "render": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}" - }, - "6": { - "question": "Indica più precisamente dove si trova il defibrillatore (in inglese)", - "render": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}" - }, - "7": { - "question": "Indica più precisamente dove si trova il defibrillatore (in francese)", - "render": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}" - }, - "9": { - "question": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", - "render": "Numero identificativo ufficiale di questo dispositivo:{ref}" - }, - "10": { - "question": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", - "render": "Indirizzo email per le domande su questo defibrillatore:{email}" - }, - "11": { - "question": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", - "render": "Numero di telefono per le domande su questo defibrillatore:{phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "Aperto 24/7 (festivi inclusi)" @@ -810,11 +795,15 @@ "question": "In quali orari è disponibile questo defibrillatore?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", - "render": "Informazioni supplementari: {description}" + "defibrillator-phone": { + "question": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", + "render": "Numero di telefono per le domande su questo defibrillatore:{phone}" }, - "14": { + "defibrillator-ref": { + "question": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", + "render": "Numero identificativo ufficiale di questo dispositivo:{ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Verificato oggi!" @@ -822,10 +811,6 @@ }, "question": "Quando è stato verificato per l’ultima volta questo defibrillatore?", "render": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}" - }, - "15": { - "question": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", - "render": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}" } }, "title": { @@ -840,11 +825,22 @@ "name": "Acqua potabile", "presets": { "0": { - "title": "Acqua potabile" + "title": "acqua potabile" } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "È facile riempire d’acqua le bottiglie" + }, + "1": { + "then": "Le bottiglie d’acqua potrebbero non entrare" + } + }, + "question": "Quanto è facile riempire d’acqua le bottiglie?" + }, + "Still in use?": { "mappings": { "0": { "then": "La fontanella funziona" @@ -859,18 +855,7 @@ "question": "Questo punto di acqua potabile è sempre funzionante?", "render": "Lo stato operativo è {operational_status}" }, - "2": { - "mappings": { - "0": { - "then": "È facile riempire d’acqua le bottiglie" - }, - "1": { - "then": "Le bottiglie d’acqua potrebbero non entrare" - } - }, - "question": "Quanto è facile riempire d’acqua le bottiglie?" - }, - "3": { + "render-closest-drinking-water": { "render": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri" } }, @@ -886,10 +871,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente." }, - "2": { + "ghost_bike-inscription": { + "question": "Che cosa è scritto sulla bici fantasma?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Nessun nome scritto sulla bici" @@ -898,15 +887,11 @@ "question": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", "render": "In ricordo di {name}" }, - "3": { + "ghost_bike-source": { "question": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", "render": "Sono disponibili ulteriori informazioni" }, - "4": { - "question": "Che cosa è scritto sulla bici fantasma?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Quando è stata installata questa bici fantasma?", "render": "Piazzata in data {start_date}" } @@ -924,7 +909,7 @@ "name": "Pannelli informativi", "presets": { "0": { - "title": "Pannello informativo" + "title": "pannello informativo" } }, "title": { @@ -941,16 +926,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Questa mappa si basa su OpenStreetMap" - } - }, - "question": "Su quali dati si basa questa mappa?", - "render": "Questa mappa si basa su {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL" @@ -969,6 +945,15 @@ } }, "question": "L’attribuzione a OpenStreetMap è presente?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Questa mappa si basa su OpenStreetMap" + } + }, + "question": "Su quali dati si basa questa mappa?", + "render": "Questa mappa si basa su {map_source}" } }, "title": { @@ -977,7 +962,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", + "render": "{curator} è il curatore di questa riserva naturale" + }, + "Dogs?": { "mappings": { "0": { "then": "I cani devono essere tenuti al guinzaglio" @@ -991,23 +980,19 @@ }, "question": "I cani sono ammessi in questa riserva naturale?" }, - "6": { - "question": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?" - }, - "7": { - "question": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", - "render": "{curator} è il curatore di questa riserva naturale" - }, - "8": { + "Email": { "question": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Area: {_surface:ha} ha" + }, + "Website": { + "question": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?" + }, + "phone": { "question": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", "render": "{phone}" - }, - "12": { - "render": "Area: {_surface:ha} ha" } } }, @@ -1016,11 +1001,11 @@ "name": "Tavoli da picnic", "presets": { "0": { - "title": "Tavolo da picnic" + "title": "tavolo da picnic" } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "È un tavolo da picnic in legno" @@ -1046,7 +1031,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Completamente accessibile in sedia a rotelle" + }, + "1": { + "then": "Accesso limitato in sedia a rotelle" + }, + "2": { + "then": "Non accessibile in sedia a rotelle" + } + }, + "question": "Il campetto è accessibile a persone in sedia a rotelle?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessibile pubblicamente" + }, + "1": { + "then": "Accessibile pubblicamente" + }, + "2": { + "then": "Accessibile solamente ai clienti dell’attività che lo gestisce" + }, + "3": { + "then": "Accessibile solamente agli studenti della scuola" + }, + "4": { + "then": "Non accessibile" + } + }, + "question": "Questo parco giochi è pubblicamente accessibile?" + }, + "playground-email": { + "question": "Qual è l’indirizzo email del gestore di questo parco giochi?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Questo parco giochi è illuminato di notte" + }, + "1": { + "then": "Questo parco giochi non è illuminato di notte" + } + }, + "question": "È illuminato di notte questo parco giochi?" + }, + "playground-max_age": { + "question": "Qual è l’età massima per accedere a questo parco giochi?", + "render": "Accessibile ai bambini di età inferiore a {max_age}" + }, + "playground-min_age": { + "question": "Qual è l’età minima per accedere a questo parco giochi?", + "render": "Accessibile ai bambini di almeno {min_age} anni" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Si può accedere dall'alba al tramonto" + }, + "1": { + "then": "Si può sempre accedere" + }, + "2": { + "then": "Si può sempre accedere" + } + }, + "question": "Quando si può accedere a questo campetto?" + }, + "playground-operator": { + "question": "Chi è il responsabile di questo parco giochi?", + "render": "Gestito da {operator}" + }, + "playground-phone": { + "question": "Qual è il numero di telefono del gestore del campetto?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "La superficie è prato" @@ -1075,85 +1139,6 @@ }, "question": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", "render": "La superficie è {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Questo parco giochi è illuminato di notte" - }, - "1": { - "then": "Questo parco giochi non è illuminato di notte" - } - }, - "question": "È illuminato di notte questo parco giochi?" - }, - "3": { - "question": "Qual è l’età minima per accedere a questo parco giochi?", - "render": "Accessibile ai bambini di almeno {min_age} anni" - }, - "4": { - "question": "Qual è l’età massima per accedere a questo parco giochi?", - "render": "Accessibile ai bambini di età inferiore a {max_age}" - }, - "5": { - "question": "Chi è il responsabile di questo parco giochi?", - "render": "Gestito da {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessibile pubblicamente" - }, - "1": { - "then": "Accessibile pubblicamente" - }, - "2": { - "then": "Accessibile solamente ai clienti dell’attività che lo gestisce" - }, - "3": { - "then": "Accessibile solamente agli studenti della scuola" - }, - "4": { - "then": "Non accessibile" - } - }, - "question": "Questo parco giochi è pubblicamente accessibile?" - }, - "7": { - "question": "Qual è l’indirizzo email del gestore di questo parco giochi?", - "render": "{email}" - }, - "8": { - "question": "Qual è il numero di telefono del gestore del campetto?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Completamente accessibile in sedia a rotelle" - }, - "1": { - "then": "Accesso limitato in sedia a rotelle" - }, - "2": { - "then": "Non accessibile in sedia a rotelle" - } - }, - "question": "Il campetto è accessibile a persone in sedia a rotelle?" - }, - "10": { - "mappings": { - "0": { - "then": "Si può accedere dall'alba al tramonto" - }, - "1": { - "then": "Si può sempre accedere" - }, - "2": { - "then": "Si può sempre accedere" - } - }, - "question": "Quando si può accedere a questo campetto?" } }, "title": { @@ -1174,20 +1159,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Questa microbiblioteca non ha un nome proprio" - } - }, - "question": "Come si chiama questa microbiblioteca pubblica?", - "render": "Questa microbiblioteca si chiama {name}" - }, - "3": { - "question": "Quanti libri può contenere questa microbiblioteca?", - "render": "Questa microbiblioteca può contenere fino a {capacity} libri" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Principalmente libri per l'infanzia" @@ -1201,7 +1173,18 @@ }, "question": "Che tipo di libri si possono trovare in questa microbiblioteca?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "È ad accesso libero" + }, + "1": { + "then": "L'accesso è riservato ai clienti" + } + }, + "question": "Questa microbiblioteca è ad accesso libero?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Questa microbiblioteca si trova al chiuso" @@ -1215,22 +1198,7 @@ }, "question": "Questa microbiblioteca si trova all'aperto?" }, - "6": { - "mappings": { - "0": { - "then": "È ad accesso libero" - }, - "1": { - "then": "L'accesso è riservato ai clienti" - } - }, - "question": "Questa microbiblioteca è ad accesso libero?" - }, - "7": { - "question": "Chi mantiene questa microbiblioteca?", - "render": "È gestita da {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Fa parte della rete 'Little Free Library'" @@ -1242,7 +1210,24 @@ "question": "Questa microbiblioteca fa parte di una rete?", "render": "Questa microbiblioteca fa parte di {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Quanti libri può contenere questa microbiblioteca?", + "render": "Questa microbiblioteca può contenere fino a {capacity} libri" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Questa microbiblioteca non ha un nome proprio" + } + }, + "question": "Come si chiama questa microbiblioteca pubblica?", + "render": "Questa microbiblioteca si chiama {name}" + }, + "public_bookcase-operator": { + "question": "Chi mantiene questa microbiblioteca?", + "render": "È gestita da {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Questa microbiblioteca non fa parte di una rete" @@ -1251,11 +1236,11 @@ "question": "Qual è il numero identificativo di questa microbiblioteca?", "render": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Quando è stata inaugurata questa microbiblioteca?", "render": "È stata inaugurata il {start_date}" }, - "11": { + "public_bookcase-website": { "question": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", "render": "Maggiori informazioni sul sito web" } @@ -1271,7 +1256,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "La superficie è erba" @@ -1314,7 +1299,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Aperto al pubblico" + }, + "1": { + "then": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)" + }, + "2": { + "then": "Accesso limitato ai membri dell'associazione" + }, + "3": { + "then": "Privato - non aperto al pubblico" + } + }, + "question": "Questo campo sportivo è aperto al pubblico?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "La prenotazione è obbligatoria per usare questo campo sportivo" + }, + "1": { + "then": "La prenotazione è consigliata per usare questo campo sportivo" + }, + "2": { + "then": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo" + }, + "3": { + "then": "Non è possibile prenotare" + } + }, + "question": "È necessario prenotarsi per usare questo campo sportivo?" + }, + "sport_pitch-email": { + "question": "Qual è l'indirizzo email del gestore?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Sempre aperto" + } + }, + "question": "Quando è aperto questo campo sportivo?" + }, + "sport_pitch-phone": { + "question": "Qual è il numero di telefono del gestore?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Qui si gioca a basket" @@ -1338,7 +1371,7 @@ "question": "Quale sport si gioca qui?", "render": "Qui si gioca a {sport}" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "La superficie è erba" @@ -1358,54 +1391,6 @@ }, "question": "Qual è la superficie di questo campo sportivo?", "render": "La superficie è {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Aperto al pubblico" - }, - "1": { - "then": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)" - }, - "2": { - "then": "Accesso limitato ai membri dell'associazione" - }, - "3": { - "then": "Privato - non aperto al pubblico" - } - }, - "question": "Questo campo sportivo è aperto al pubblico?" - }, - "4": { - "mappings": { - "0": { - "then": "La prenotazione è obbligatoria per usare questo campo sportivo" - }, - "1": { - "then": "La prenotazione è consigliata per usare questo campo sportivo" - }, - "2": { - "then": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo" - }, - "3": { - "then": "Non è possibile prenotare" - } - }, - "question": "È necessario prenotarsi per usare questo campo sportivo?" - }, - "5": { - "question": "Qual è il numero di telefono del gestore?" - }, - "6": { - "question": "Qual è l'indirizzo email del gestore?" - }, - "7": { - "mappings": { - "1": { - "then": "Sempre aperto" - } - }, - "question": "Quando è aperto questo campo sportivo?" } }, "title": { @@ -1415,7 +1400,7 @@ "surveillance_camera": { "name": "Videocamere di sorveglianza", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Una videocamera fissa (non semovente)" @@ -1429,34 +1414,7 @@ }, "question": "Di che tipo di videocamera si tratta?" }, - "2": { - "mappings": { - "0": { - "then": "Punta in direzione {direction}" - } - }, - "question": "In quale direzione geografica punta questa videocamera?", - "render": "Punta in direzione {camera:direction}" - }, - "3": { - "question": "Chi gestisce questa videocamera a circuito chiuso?", - "render": "È gestita da {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." - }, - "1": { - "then": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" - }, - "2": { - "then": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." - } - }, - "question": "Che cosa sorveglia questa videocamera" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Questa videocamera si trova al chiuso" @@ -1470,11 +1428,29 @@ }, "question": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" }, - "6": { + "Level": { "question": "A che piano si trova questa videocamera?", "render": "Si trova al piano {level}" }, - "7": { + "Operator": { + "question": "Chi gestisce questa videocamera a circuito chiuso?", + "render": "È gestita da {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." + }, + "1": { + "then": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" + }, + "2": { + "then": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." + } + }, + "question": "Che cosa sorveglia questa videocamera" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Sorveglia un parcheggio" @@ -1498,7 +1474,7 @@ "question": "Che cosa è sorvegliato qui?", "render": " Sorveglia una {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Questa telecamera è posizionata contro un muro" @@ -1512,6 +1488,15 @@ }, "question": "Com'è posizionata questa telecamera?", "render": "Metodo di montaggio: {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Punta in direzione {direction}" + } + }, + "question": "In quale direzione geografica punta questa videocamera?", + "render": "Punta in direzione {camera:direction}" } }, "title": { @@ -1523,15 +1508,15 @@ "presets": { "0": { "description": "Servizi igienici aperti al pubblico", - "title": "Servizi igienici" + "title": "servizi igienici" }, "1": { "description": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle", - "title": "Servizi igienici accessibili per persone in sedia a rotelle" + "title": "servizi igienici accessibili per persone in sedia a rotelle" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Accesso pubblico" @@ -1552,61 +1537,7 @@ "question": "Questi servizi igienici sono aperti al pubblico?", "render": "L'accesso è {access}" }, - "2": { - "mappings": { - "0": { - "then": "Questi servizi igienici sono a pagamento" - }, - "1": { - "then": "Gratis" - } - }, - "question": "Questi servizi igienici sono gratuiti?" - }, - "3": { - "question": "Quanto costa l'accesso a questi servizi igienici?", - "render": "La tariffa è {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "1": { - "then": "Non accessibile in sedia a rotelle" - } - }, - "question": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "5": { - "mappings": { - "0": { - "then": "Ci sono solo WC con sedile" - }, - "1": { - "then": "Ci sono solo urinali" - }, - "2": { - "then": "Ci sono solo turche" - }, - "3": { - "then": "Ci sono sia sedili, sia urinali" - } - }, - "question": "Di che tipo di servizi igienici si tratta?" - }, - "6": { - "mappings": { - "0": { - "then": "È disponibile un fasciatoio" - }, - "1": { - "then": "Non è disponibile un fasciatoio" - } - }, - "question": "È disponibile un fasciatoio (per cambiare i pannolini)?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "Il fasciatoio è nei servizi igienici femminili. " @@ -1623,6 +1554,60 @@ }, "question": "Dove si trova il fasciatoio?", "render": "Il fasciatoio si trova presso {changing_table:location}" + }, + "toilet-charge": { + "question": "Quanto costa l'accesso a questi servizi igienici?", + "render": "La tariffa è {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "È disponibile un fasciatoio" + }, + "1": { + "then": "Non è disponibile un fasciatoio" + } + }, + "question": "È disponibile un fasciatoio (per cambiare i pannolini)?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Questi servizi igienici sono a pagamento" + }, + "1": { + "then": "Gratis" + } + }, + "question": "Questi servizi igienici sono gratuiti?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Ci sono solo WC con sedile" + }, + "1": { + "then": "Ci sono solo urinali" + }, + "2": { + "then": "Ci sono solo turche" + }, + "3": { + "then": "Ci sono sia sedili, sia urinali" + } + }, + "question": "Di che tipo di servizi igienici si tratta?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "1": { + "then": "Non accessibile in sedia a rotelle" + } + }, + "question": "C'è un WC riservato alle persone in sedia a rotelle" } }, "title": { @@ -1646,29 +1631,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Altezza: {height} m" - } - }, - "render": "Altezza: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Latifoglia" + "then": "Caduco: l’albero perde le sue foglie per un periodo dell’anno." }, "1": { - "then": "\"\"/ Aghifoglia" - }, - "2": { - "then": "\"\"/ Privo di foglie (permanente)" + "then": "Sempreverde." } }, - "question": "Si tratta di un albero latifoglia o aghifoglia?" + "question": "È un sempreverde o caduco?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione." @@ -1697,27 +1671,15 @@ }, "question": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Caduco: l’albero perde le sue foglie per un periodo dell’anno." - }, - "1": { - "then": "Sempreverde." + "then": "Altezza: {height} m" } }, - "question": "È un sempreverde o caduco?" + "render": "Altezza: {height}" }, - "5": { - "mappings": { - "0": { - "then": "L’albero non ha un nome." - } - }, - "question": "L’albero ha un nome?", - "render": "Nome: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders" @@ -1737,11 +1699,34 @@ }, "question": "Quest’albero è registrato come patrimonio?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Latifoglia" + }, + "1": { + "then": "\"\"/ Aghifoglia" + }, + "2": { + "then": "\"\"/ Privo di foglie (permanente)" + } + }, + "question": "Si tratta di un albero latifoglia o aghifoglia?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "L’albero non ha un nome." + } + }, + "question": "L’albero ha un nome?", + "render": "Nome: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Qual è l’ID Wikidata per questo albero?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -1764,7 +1749,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Vuoi aggiungere una descrizione?" } }, diff --git a/langs/layers/ja.json b/langs/layers/ja.json index 24b81b31b..28607d857 100644 --- a/langs/layers/ja.json +++ b/langs/layers/ja.json @@ -3,12 +3,12 @@ "description": "充電ステーション", "name": "充電ステーション", "tagRenderings": { - "41": { - "question": "この充電ステーションはいつオープンしますか?" - }, - "42": { + "Auth phone": { "question": "この充電ステーションの運営チェーンはどこですか?", "render": "{network}" + }, + "Authentication": { + "question": "この充電ステーションはいつオープンしますか?" } }, "title": { @@ -17,7 +17,7 @@ }, "food": { "tagRenderings": { - "17": { + "friture-take-your-container": { "mappings": { "0": { "then": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index 12821e829..c515216b9 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -3,12 +3,11 @@ "name": "Benker", "presets": { "0": { - "description": "Legg til en ny benk", - "title": "Benk" + "title": "benk" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Rygglene: Ja" @@ -20,34 +19,7 @@ "question": "Har denne beken et rygglene?", "render": "Rygglene" }, - "2": { - "question": "Hvor mange sitteplasser har denne benken?", - "render": "{seats} seter" - }, - "3": { - "mappings": { - "0": { - "then": "Materiale: tre" - }, - "1": { - "then": "Materiale: metall" - }, - "2": { - "then": "Materiale: stein" - }, - "3": { - "then": "Materiale: betong" - }, - "4": { - "then": "Materiale: plastikk" - }, - "5": { - "then": "Materiale: stål" - } - }, - "render": "Materiale: {material}" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Farge: brun" @@ -75,6 +47,33 @@ } }, "render": "Farge: {colour}" + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiale: tre" + }, + "1": { + "then": "Materiale: metall" + }, + "2": { + "then": "Materiale: stein" + }, + "3": { + "then": "Materiale: betong" + }, + "4": { + "then": "Materiale: plastikk" + }, + "5": { + "then": "Materiale: stål" + } + }, + "render": "Materiale: {material}" + }, + "bench-seats": { + "question": "Hvor mange sitteplasser har denne benken?", + "render": "{seats} seter" } }, "title": { @@ -89,11 +88,7 @@ }, "bicycle_library": { "tagRenderings": { - "1": { - "question": "Hva heter dette sykkelbiblioteket?", - "render": "Dette sykkelbiblioteket heter {name}" - }, - "6": { + "bicycle_library-charge": { "mappings": { "0": { "then": "Det er gratis å leie en sykkel" @@ -101,6 +96,10 @@ }, "question": "Hvor mye koster det å leie en sykkel?", "render": "Sykkelleie koster {charge}" + }, + "bicycle_library-name": { + "question": "Hva heter dette sykkelbiblioteket?", + "render": "Dette sykkelbiblioteket heter {name}" } } }, @@ -108,11 +107,11 @@ "description": "En ladestasjon", "name": "Ladestasjoner", "tagRenderings": { - "41": { - "question": "Når åpnet denne ladestasjonen?" - }, - "42": { + "Auth phone": { "render": "{network}" + }, + "Authentication": { + "question": "Når åpnet denne ladestasjonen?" } }, "title": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 97668f8ab..0ba838cc7 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -13,18 +13,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Een fietser kan hier langs." - }, - "1": { - "then": "Een fietser kan hier niet langs." - } - }, - "question": "Kan een fietser langs deze barrière?" - }, - "1": { + "Bollard type": { "mappings": { "0": { "then": "Verwijderbare paal" @@ -44,7 +33,7 @@ }, "question": "Wat voor soort paal is dit?" }, - "2": { + "Cycle barrier type": { "mappings": { "0": { "then": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " @@ -61,20 +50,31 @@ }, "question": "Wat voor fietshekjes zijn dit?" }, - "3": { + "MaxWidth": { "question": "Hoe breed is de ruimte naast de barrière?", "render": "Maximumbreedte: {maxwidth:physical} m" }, - "4": { + "Overlap (cyclebarrier)": { + "question": "Hoeveel overlappen de barrières?" + }, + "Space between barrier (cyclebarrier)": { "question": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?", "render": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" }, - "5": { + "Width of opening (cyclebarrier)": { "question": "Hoe breed is de smalste opening naast de barrières?", "render": "Breedte van de opening: {width:opening} m" }, - "6": { - "question": "Hoeveel overlappen de barrières?" + "bicycle=yes/no": { + "mappings": { + "0": { + "then": "Een fietser kan hier langs." + }, + "1": { + "then": "Een fietser kan hier niet langs." + } + }, + "question": "Kan een fietser langs deze barrière?" } }, "title": { @@ -93,12 +93,11 @@ "name": "Zitbanken", "presets": { "0": { - "description": "Voeg een nieuwe zitbank toe", - "title": "Zitbank" + "title": "zitbank" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Heeft een rugleuning" @@ -110,39 +109,7 @@ "question": "Heeft deze zitbank een rugleuning?", "render": "Rugleuning" }, - "2": { - "question": "Hoeveel zitplaatsen heeft deze bank?", - "render": "{seats} zitplaatsen" - }, - "3": { - "mappings": { - "0": { - "then": "Gemaakt uit hout" - }, - "1": { - "then": "Gemaakt uit metaal" - }, - "2": { - "then": "Gemaakt uit steen" - }, - "3": { - "then": "Gemaakt uit beton" - }, - "4": { - "then": "Gemaakt uit plastiek" - }, - "5": { - "then": "Gemaakt uit staal" - } - }, - "question": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", - "render": "Gemaakt van {material}" - }, - "4": { - "question": "In welke richting kijk je wanneer je op deze zitbank zit?", - "render": "Wanneer je op deze bank zit, dan kijk je in {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "De kleur is bruin" @@ -172,7 +139,39 @@ "question": "Welke kleur heeft deze zitbank?", "render": "Kleur: {colour}" }, - "6": { + "bench-direction": { + "question": "In welke richting kijk je wanneer je op deze zitbank zit?", + "render": "Wanneer je op deze bank zit, dan kijk je in {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Gemaakt uit hout" + }, + "1": { + "then": "Gemaakt uit metaal" + }, + "2": { + "then": "Gemaakt uit steen" + }, + "3": { + "then": "Gemaakt uit beton" + }, + "4": { + "then": "Gemaakt uit plastiek" + }, + "5": { + "then": "Gemaakt uit staal" + } + }, + "question": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", + "render": "Gemaakt van {material}" + }, + "bench-seats": { + "question": "Hoeveel zitplaatsen heeft deze bank?", + "render": "{seats} zitplaatsen" + }, + "bench-survey:date": { "question": "Wanneer is deze laatste bank laatst gesurveyed?", "render": "Deze bank is laatst gesurveyd op {survey:date}" } @@ -184,11 +183,11 @@ "bench_at_pt": { "name": "Zitbanken aan bushaltes", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Leunbank" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -213,23 +212,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van deze fietsbieb?", - "render": "Deze fietsbieb heet {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Een fiets huren is gratis" - }, - "1": { - "then": "Een fiets huren kost €20/jaar en €20 waarborg" - } - }, - "question": "Hoeveel kost het huren van een fiets?", - "render": "Een fiets huren kost {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Aanbod voor kinderen" @@ -242,6 +225,22 @@ } }, "question": "Voor wie worden hier fietsen aangeboden?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Een fiets huren is gratis" + }, + "1": { + "then": "Een fiets huren kost €20/jaar en €20 waarborg" + } + }, + "question": "Hoeveel kost het huren van een fiets?", + "render": "Een fiets huren kost {charge}" + }, + "bicycle_library-name": { + "question": "Wat is de naam van deze fietsbieb?", + "render": "Deze fietsbieb heet {name}" } }, "title": { @@ -256,7 +255,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Deze verkoopsautomaat werkt" @@ -284,11 +283,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van dit fietscafé?", - "render": "Dit fietscafé heet {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Dit fietscafé biedt een fietspomp aan voor eender wie" @@ -299,18 +294,20 @@ }, "question": "Biedt dit fietscafé een fietspomp aan voor iedereen?" }, - "3": { - "mappings": { - "0": { - "then": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen" - }, - "1": { - "then": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen" - } - }, - "question": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?" + "bike_cafe-email": { + "question": "Wat is het email-adres van {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Wat is de naam van dit fietscafé?", + "render": "Dit fietscafé heet {name}" + }, + "bike_cafe-opening_hours": { + "question": "Wanneer is dit fietscafé geopend?" + }, + "bike_cafe-phone": { + "question": "Wat is het telefoonnummer van {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Dit fietscafé herstelt fietsen" @@ -321,17 +318,19 @@ }, "question": "Herstelt dit fietscafé fietsen?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen" + }, + "1": { + "then": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen" + } + }, + "question": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?" + }, + "bike_cafe-website": { "question": "Wat is de website van {name}?" - }, - "6": { - "question": "Wat is het telefoonnummer van {name}?" - }, - "7": { - "question": "Wat is het email-adres van {name}?" - }, - "8": { - "question": "Wanneer is dit fietscafé geopend?" } }, "title": { @@ -359,20 +358,6 @@ "render": "Fietsschoonmaakpunt" } }, - "bike_monitoring_station": { - "name": "Telstation", - "title": { - "mappings": { - "0": { - "then": "Fietstelstation {name}" - }, - "1": { - "then": "Fietstelstation {ref}" - } - }, - "render": "Fietstelstation" - } - }, "bike_parking": { "name": "Fietsparking", "presets": { @@ -381,7 +366,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Publiek toegankelijke fietsenstalling" + }, + "1": { + "then": "Klanten van de zaak of winkel" + }, + "2": { + "then": "Private fietsenstalling van een school, een bedrijf, ..." + } + }, + "question": "Wie mag er deze fietsenstalling gebruiken?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Nietjes " @@ -411,7 +411,40 @@ "question": "Van welk type is deze fietsparking?", "render": "Dit is een fietsparking van het type: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", + "render": "Plaats voor {capacity} fietsen" + }, + "Cargo bike capacity?": { + "question": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", + "render": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Deze parking heeft plaats voor bakfietsen" + }, + "1": { + "then": "Er zijn speciale plaatsen voorzien voor bakfietsen" + }, + "2": { + "then": "Je mag hier geen bakfietsen parkeren" + } + }, + "question": "Heeft deze fietsparking plaats voor bakfietsen?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Deze parking is overdekt (er is een afdak)" + }, + "1": { + "then": "Deze parking is niet overdekt" + } + }, + "question": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw." + }, + "Underground?": { "mappings": { "0": { "then": "Ondergrondse parking" @@ -430,54 +463,6 @@ } }, "question": "Wat is de relatieve locatie van deze parking??" - }, - "3": { - "mappings": { - "0": { - "then": "Deze parking is overdekt (er is een afdak)" - }, - "1": { - "then": "Deze parking is niet overdekt" - } - }, - "question": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw." - }, - "4": { - "question": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", - "render": "Plaats voor {capacity} fietsen" - }, - "5": { - "mappings": { - "0": { - "then": "Publiek toegankelijke fietsenstalling" - }, - "1": { - "then": "Klanten van de zaak of winkel" - }, - "2": { - "then": "Private fietsenstalling van een school, een bedrijf, ..." - } - }, - "question": "Wie mag er deze fietsenstalling gebruiken?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Deze parking heeft plaats voor bakfietsen" - }, - "1": { - "then": "Er zijn speciale plaatsen voorzien voor bakfietsen" - }, - "2": { - "then": "Je mag hier geen bakfietsen parkeren" - } - }, - "question": "Heeft deze fietsparking plaats voor bakfietsen?" - }, - "7": { - "question": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", - "render": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen" } }, "title": { @@ -500,7 +485,21 @@ } }, "tagRenderings": { - "1": { + "Email maintainer": { + "render": "Rapporteer deze fietspomp als kapot" + }, + "Operational status": { + "mappings": { + "0": { + "then": "De fietspomp is kapot" + }, + "1": { + "then": "De fietspomp werkt nog" + } + }, + "question": "Werkt de fietspomp nog?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Er is enkel een pomp aanwezig" @@ -514,28 +513,7 @@ }, "question": "Welke functies biedt dit fietspunt?" }, - "2": { - "question": "Wie beheert deze fietspomp?", - "render": "Beheer door {operator}" - }, - "3": { - "question": "Wat is het email-adres van de beheerder?" - }, - "4": { - "question": "Wat is het telefoonnummer van de beheerder?" - }, - "5": { - "mappings": { - "0": { - "then": "Dag en nacht open" - }, - "1": { - "then": "Dag en nacht open" - } - }, - "question": "Wanneer is dit fietsherstelpunt open?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Er is een reparatieset voor je ketting" @@ -546,7 +524,7 @@ }, "question": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Er is een haak of standaard" @@ -557,21 +535,53 @@ }, "question": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "De fietspomp is kapot" + "then": "Manuele pomp" }, "1": { - "then": "De fietspomp werkt nog" + "then": "Electrische pomp" } }, - "question": "Werkt de fietspomp nog?" + "question": "Is dit een electrische fietspomp?" }, - "9": { - "render": "Rapporteer deze fietspomp als kapot" + "bike_repair_station-email": { + "question": "Wat is het email-adres van de beheerder?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Er is een luchtdrukmeter" + }, + "1": { + "then": "Er is geen luchtdrukmeter" + }, + "2": { + "then": "Er is een luchtdrukmeter maar die is momenteel defect" + } + }, + "question": "Heeft deze pomp een luchtdrukmeter?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Dag en nacht open" + }, + "1": { + "then": "Dag en nacht open" + } + }, + "question": "Wanneer is dit fietsherstelpunt open?" + }, + "bike_repair_station-operator": { + "question": "Wie beheert deze fietspomp?", + "render": "Beheer door {operator}" + }, + "bike_repair_station-phone": { + "question": "Wat is het telefoonnummer van de beheerder?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (ook gekend als Presta)" @@ -585,31 +595,6 @@ }, "question": "Welke ventielen werken er met de pomp?", "render": "Deze pomp werkt met de volgende ventielen: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manuele pomp" - }, - "1": { - "then": "Electrische pomp" - } - }, - "question": "Is dit een electrische fietspomp?" - }, - "12": { - "mappings": { - "0": { - "then": "Er is een luchtdrukmeter" - }, - "1": { - "then": "Er is geen luchtdrukmeter" - }, - "2": { - "then": "Er is een luchtdrukmeter maar die is momenteel defect" - } - }, - "question": "Heeft deze pomp een luchtdrukmeter?" } }, "title": { @@ -642,34 +627,46 @@ } }, "tagRenderings": { - "1": { - "render": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten." - }, - "2": { - "question": "Wat is de naam van deze fietszaak?", - "render": "Deze fietszaak heet {name}" - }, - "3": { - "question": "Wat is de website van {name}?" - }, - "4": { - "question": "Wat is het telefoonnummer van {name}?" - }, - "5": { - "question": "Wat is het email-adres van {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Deze winkel verkoopt fietsen" + "then": "Deze winkel biedt een fietspomp aan voor iedereen" }, "1": { - "then": "Deze winkel verkoopt geen fietsen" + "then": "Deze winkel biedt geen fietspomp aan voor eender wie" + }, + "2": { + "then": "Er is een fietspomp, deze is apart aangeduid" } }, - "question": "Verkoopt deze fietszaak fietsen?" + "question": "Biedt deze winkel een fietspomp aan voor iedereen?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Deze winkel biedt fietsschoonmaak aan" + }, + "1": { + "then": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken" + }, + "2": { + "then": "Deze winkel biedt geen fietsschoonmaak aan" + } + }, + "question": "Biedt deze winkel een fietsschoonmaak aan?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Deze winkel verhuurt fietsen" + }, + "1": { + "then": "Deze winkel verhuurt geen fietsen" + } + }, + "question": "Verhuurt deze winkel fietsen?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Deze winkel herstelt fietsen" @@ -686,18 +683,7 @@ }, "question": "Herstelt deze winkel fietsen?" }, - "11": { - "mappings": { - "0": { - "then": "Deze winkel verhuurt fietsen" - }, - "1": { - "then": "Deze winkel verhuurt geen fietsen" - } - }, - "question": "Verhuurt deze winkel fietsen?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Deze winkel verkoopt tweedehands fietsen" @@ -711,21 +697,18 @@ }, "question": "Verkoopt deze winkel tweedehands fietsen?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Deze winkel biedt een fietspomp aan voor iedereen" + "then": "Deze winkel verkoopt fietsen" }, "1": { - "then": "Deze winkel biedt geen fietspomp aan voor eender wie" - }, - "2": { - "then": "Er is een fietspomp, deze is apart aangeduid" + "then": "Deze winkel verkoopt geen fietsen" } }, - "question": "Biedt deze winkel een fietspomp aan voor iedereen?" + "question": "Verkoopt deze fietszaak fietsen?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen" @@ -739,19 +722,21 @@ }, "question": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?" }, - "15": { - "mappings": { - "0": { - "then": "Deze winkel biedt fietsschoonmaak aan" - }, - "1": { - "then": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken" - }, - "2": { - "then": "Deze winkel biedt geen fietsschoonmaak aan" - } - }, - "question": "Biedt deze winkel een fietsschoonmaak aan?" + "bike_shop-email": { + "question": "Wat is het email-adres van {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten." + }, + "bike_shop-name": { + "question": "Wat is de naam van deze fietszaak?", + "render": "Deze fietszaak heet {name}" + }, + "bike_shop-phone": { + "question": "Wat is het telefoonnummer van {name}?" + }, + "bike_shop-website": { + "question": "Wat is de website van {name}?" } }, "title": { @@ -796,7 +781,7 @@ } }, "tagRenderings": { - "1": { + "binocular-charge": { "mappings": { "0": { "then": "Gratis te gebruiken" @@ -805,7 +790,7 @@ "question": "Hoeveel moet men betalen om deze verrekijker te gebruiken?", "render": "Deze verrekijker gebruiken kost {charge}" }, - "2": { + "binocular-direction": { "question": "Welke richting kijkt men uit als men door deze verrekijker kijkt?", "render": "Kijkt richting {direction}°" } @@ -842,11 +827,11 @@ "presets": { "0": { "description": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden", - "title": "Vogelkijkhut" + "title": "vogelkijkhut" }, "1": { "description": "Een vogelkijkwand waarachter men kan staan om vogels te kijken", - "title": "Vogelkijkwand" + "title": "vogelkijkwand" } }, "size": { @@ -856,7 +841,7 @@ "render": "3" }, "tagRenderings": { - "1": { + "bird-hide-shelter-or-wall": { "mappings": { "0": { "then": "Vogelkijkwand" @@ -873,7 +858,7 @@ }, "question": "Is dit een kijkwand of kijkhut?" }, - "2": { + "bird-hide-wheelchair": { "mappings": { "0": { "then": "Er zijn speciale voorzieningen voor rolstoelen" @@ -890,7 +875,7 @@ }, "question": "Is deze vogelkijkplaats rolstoeltoegankelijk?" }, - "3": { + "birdhide-operator": { "mappings": { "0": { "then": "Beheer door Natuurpunt" @@ -944,11 +929,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van dit café?", - "render": "De naam van dit café is {name}" - }, - "2": { + "Classification": { "mappings": { "0": { "then": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " @@ -967,6 +948,10 @@ } }, "question": "Welk soort café is dit?" + }, + "Name": { + "question": "Wat is de naam van dit café?", + "render": "De naam van dit café is {name}" } }, "title": { @@ -1024,16 +1009,24 @@ }, "9": { "question": "Heeft een " + }, + "10": { + "question": "Heeft een Type 2 met kabel (J1772) " + }, + "11": { + "question": "Heeft een " + }, + "12": { + "question": "Heeft een " + }, + "13": { + "question": "Heeft een " } } } }, "tagRenderings": { - "3": { - "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", - "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "4": { + "Available_charging_stations (generated)": { "mappings": { "0": { "then": "

Schuko stekker zonder aardingspin (CEE7/4 type F)

" @@ -1087,377 +1080,35 @@ "then": "

" }, "17": { - "then": "

" + "then": " " + }, + "18": { + "then": " Type 2 met kabel (J1772)" + }, + "19": { + "then": " Type 2 met kabel (J1772)" + }, + "20": { + "then": " " + }, + "21": { + "then": " " + }, + "22": { + "then": " " + }, + "23": { + "then": " " + }, + "24": { + "then": " " + }, + "25": { + "then": " " } } }, - "5": { - "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", - "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "9": { - "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", - "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "10": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", - "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - }, - "1": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "13": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "14": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 120 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "17": { - "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", - "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "21": { - "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", - "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - }, - "2": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - }, - "3": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "25": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "26": { - "mappings": { - "0": { - "then": " heeft een spanning van 400 volt" - }, - "1": { - "then": " heeft een spanning van 1000 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 50 A" - }, - "1": { - "then": " levert een stroom van maximaal 125 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 62.5 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "3": { - "then": " levert een vermogen van maximaal 350 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "29": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "30": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "33": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "34": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2:output}" - }, - "37": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "38": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "44": { - "mappings": { - "0": { - "then": "Gratis te gebruiken" - } - }, - "question": "Hoeveel kost het gebruik van dit oplaadpunt?", - "render": "Dit oplaadpunt gebruiken kost {charge}" - }, - "45": { - "override": { - "mappings+": { - "0": { - "then": "Betalen via een app van het netwerk" - } - } - } - }, - "46": { - "mappings": { - "0": { - "then": "Geen maximum parkeertijd" - } - }, - "question": "Hoelang mag een voertuig hier blijven staan?", - "render": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "54": { + "Operational status": { "mappings": { "0": { "then": "Dit oplaadpunt is kapot" @@ -1476,6 +1127,544 @@ } }, "question": "Is dit oplaadpunt operationeel?" + }, + "capacity": { + "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", + "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "current-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "current-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 120 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 50 A" + }, + "1": { + "then": " levert een stroom van maximaal 125 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Gratis te gebruiken" + } + }, + "question": "Hoeveel kost het gebruik van dit oplaadpunt?", + "render": "Dit oplaadpunt gebruiken kost {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "Geen maximum parkeertijd" + } + }, + "question": "Hoelang mag een voertuig hier blijven staan?", + "render": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Betalen via een app van het netwerk" + }, + "1": { + "then": "Betalen via een lidkaart van het netwerk" + } + }, + "mappings+": { + "0": { + "then": "Betalen via een app van het netwerk" + }, + "1": { + "then": "Betalen via een lidkaart van het netwerk" + } + } + } + }, + "plugs-0": { + "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", + "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "plugs-1": { + "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", + "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "plugs-10": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-11": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-12": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-2": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-3": { + "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "plugs-4": { + "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "plugs-5": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-6": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-7": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-8": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-9": { + "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + }, + "1": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + }, + "2": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + }, + "3": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 62.5 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "3": { + "then": " levert een vermogen van maximaal 350 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", + "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", + "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", + "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": " heeft een spanning van 400 volt" + }, + "1": { + "then": " heeft een spanning van 1000 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + }, + "1": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" } }, "units": { @@ -1535,32 +1724,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Oversteekplaats, zonder verkeerslichten" - }, - "1": { - "then": "Oversteekplaats met verkeerslichten" - }, - "2": { - "then": "Zebrapad" - } - }, - "question": "Wat voor oversteekplaats is dit?" - }, - "1": { - "mappings": { - "0": { - "then": "Dit is een zebrapad" - }, - "1": { - "then": "Dit is geen zebrapad" - } - }, - "question": "Is dit een zebrapad?" - }, - "2": { + "crossing-bicycle-allowed": { "mappings": { "0": { "then": "Een fietser kan deze oversteekplaats gebruiken" @@ -1571,32 +1735,7 @@ }, "question": "Is deze oversteekplaats ook voor fietsers" }, - "3": { - "mappings": { - "0": { - "then": "Deze oversteekplaats heeft een verkeerseiland in het midden" - }, - "1": { - "then": "Deze oversteekplaats heeft geen verkeerseiland in het midden" - } - }, - "question": "Heeft deze oversteekplaats een verkeerseiland in het midden?" - }, - "4": { - "mappings": { - "0": { - "then": "Deze oversteekplaats heeft een geleidelijn" - }, - "1": { - "then": "Deze oversteekplaats heeft geen geleidelijn" - }, - "2": { - "then": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." - } - }, - "question": "Heeft deze oversteekplaats een geleidelijn?" - }, - "5": { + "crossing-button": { "mappings": { "0": { "then": "Dit verkeerslicht heeft een knop voor groen licht" @@ -1607,7 +1746,43 @@ }, "question": "Heeft dit verkeerslicht een knop voor groen licht?" }, - "6": { + "crossing-continue-through-red": { + "mappings": { + "0": { + "then": "Een fietser mag wel rechtdoor gaan als het licht rood is " + }, + "1": { + "then": "Een fietser mag wel rechtdoor gaan als het licht rood is" + }, + "2": { + "then": "Een fietser mag niet rechtdoor gaan als het licht rood is" + } + }, + "question": "Mag een fietser rechtdoor gaan als het licht rood is?" + }, + "crossing-has-island": { + "mappings": { + "0": { + "then": "Deze oversteekplaats heeft een verkeerseiland in het midden" + }, + "1": { + "then": "Deze oversteekplaats heeft geen verkeerseiland in het midden" + } + }, + "question": "Heeft deze oversteekplaats een verkeerseiland in het midden?" + }, + "crossing-is-zebra": { + "mappings": { + "0": { + "then": "Dit is een zebrapad" + }, + "1": { + "then": "Dit is geen zebrapad" + } + }, + "question": "Is dit een zebrapad?" + }, + "crossing-right-turn-through-red": { "mappings": { "0": { "then": "Een fietser mag wel rechtsaf slaan als het licht rood is " @@ -1621,19 +1796,33 @@ }, "question": "Mag een fietser rechtsaf slaan als het licht rood is?" }, - "7": { + "crossing-tactile": { "mappings": { "0": { - "then": "Een fietser mag wel rechtdoor gaan als het licht rood is " + "then": "Deze oversteekplaats heeft een geleidelijn" }, "1": { - "then": "Een fietser mag wel rechtdoor gaan als het licht rood is" + "then": "Deze oversteekplaats heeft geen geleidelijn" }, "2": { - "then": "Een fietser mag niet rechtdoor gaan als het licht rood is" + "then": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." } }, - "question": "Mag een fietser rechtdoor gaan als het licht rood is?" + "question": "Heeft deze oversteekplaats een geleidelijn?" + }, + "crossing-type": { + "mappings": { + "0": { + "then": "Oversteekplaats, zonder verkeerslichten" + }, + "1": { + "then": "Oversteekplaats met verkeerslichten" + }, + "2": { + "then": "Zebrapad" + } + }, + "question": "Wat voor oversteekplaats is dit?" } }, "title": { @@ -1651,7 +1840,7 @@ "cycleways_and_roads": { "name": "Fietspaden, straten en wegen", "tagRenderings": { - "0": { + "Cycleway type for a road": { "mappings": { "0": { "then": "Er is een fietssuggestiestrook" @@ -1674,59 +1863,36 @@ }, "question": "Wat voor fietspad is hier?" }, - "1": { + "Cycleway:smoothness": { "mappings": { "0": { - "then": "Deze weg is verlicht" + "then": "Geschikt voor fijne rollers: rollerblade, skateboard" }, "1": { - "then": "Deze weg is niet verlicht" + "then": "Geschikt voor fijne wielen: racefiets" }, "2": { - "then": "Deze weg is 's nachts verlicht" + "then": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" }, "3": { - "then": "Deze weg is 24/7 verlicht" - } - }, - "question": "Is deze weg verlicht?" - }, - "2": { - "mappings": { - "0": { - "then": "Dit is een fietsstraat, en dus een 30km/h zone" - }, - "1": { - "then": "Dit is een fietsstraat" - }, - "2": { - "then": "Dit is geen fietsstraat" - } - }, - "question": "Is dit een fietsstraat?" - }, - "3": { - "mappings": { - "0": { - "then": "De maximumsnelheid is 20 km/u" - }, - "1": { - "then": "De maximumsnelheid is 30 km/u" - }, - "2": { - "then": "De maximumsnelheid is 50 km/u" - }, - "3": { - "then": "De maximumsnelheid is 70 km/u" + "then": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" }, "4": { - "then": "De maximumsnelheid is 90 km/u" + "then": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" + }, + "5": { + "then": "Geschikt voor terreinwagens: zware terreinwagen" + }, + "6": { + "then": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" + }, + "7": { + "then": "Niet geschikt voor voertuigen met wielen" } }, - "question": "Wat is de maximumsnelheid in deze straat?", - "render": "De maximumsnelheid op deze weg is {maxspeed} km/u" + "question": "Wat is de kwaliteit van dit fietspad?" }, - "4": { + "Cycleway:surface": { "mappings": { "0": { "then": "Dit fietspad is onverhard" @@ -1771,36 +1937,42 @@ "question": "Waaruit is het oppervlak van het fietspad van gemaakt?", "render": "Dit fietspad is gemaakt van {cycleway:surface}" }, - "5": { + "Is this a cyclestreet? (For a road)": { "mappings": { "0": { - "then": "Geschikt voor fijne rollers: rollerblade, skateboard" + "then": "Dit is een fietsstraat, en dus een 30km/h zone" }, "1": { - "then": "Geschikt voor fijne wielen: racefiets" + "then": "Dit is een fietsstraat" }, "2": { - "then": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" - }, - "3": { - "then": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" - }, - "4": { - "then": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" - }, - "5": { - "then": "Geschikt voor terreinwagens: zware terreinwagen" - }, - "6": { - "then": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" - }, - "7": { - "then": "Niet geschikt voor voertuigen met wielen" + "then": "Dit is geen fietsstraat" } }, - "question": "Wat is de kwaliteit van dit fietspad?" + "question": "Is dit een fietsstraat?" }, - "6": { + "Maxspeed (for road)": { + "mappings": { + "0": { + "then": "De maximumsnelheid is 20 km/u" + }, + "1": { + "then": "De maximumsnelheid is 30 km/u" + }, + "2": { + "then": "De maximumsnelheid is 50 km/u" + }, + "3": { + "then": "De maximumsnelheid is 70 km/u" + }, + "4": { + "then": "De maximumsnelheid is 90 km/u" + } + }, + "question": "Wat is de maximumsnelheid in deze straat?", + "render": "De maximumsnelheid op deze weg is {maxspeed} km/u" + }, + "Surface of the road": { "mappings": { "0": { "then": "Dit fietspad is onverhard" @@ -1845,14 +2017,27 @@ "question": "Waaruit is het oppervlak van de straat gemaakt?", "render": "Deze weg is gemaakt van {surface}" }, - "7": { + "Surface of the street": { "question": "Wat is de kwaliteit van deze straat?" }, - "8": { - "question": "Hoe breed is de rijbaan in deze straat (in meters)?", - "render": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" + "cyclelan-segregation": { + "mappings": { + "0": { + "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + }, + "1": { + "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + }, + "2": { + "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + }, + "3": { + "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + }, + "question": "Hoe is dit fietspad gescheiden van de weg?" }, - "9": { + "cycleway-lane-track-traffic-signs": { "mappings": { "0": { "then": "Verplicht fietspad " @@ -1872,7 +2057,24 @@ }, "question": "Welk verkeersbord heeft dit fietspad?" }, - "10": { + "cycleway-segregation": { + "mappings": { + "0": { + "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + }, + "1": { + "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + }, + "2": { + "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + }, + "3": { + "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + }, + "question": "Hoe is dit fietspad gescheiden van de weg?" + }, + "cycleway-traffic-signs": { "mappings": { "0": { "then": "Verplicht fietspad " @@ -1892,7 +2094,7 @@ }, "question": "Welk verkeersbord heeft dit fietspad?" }, - "11": { + "cycleway-traffic-signs-D7-supplementary": { "mappings": { "0": { "then": "" @@ -1918,7 +2120,7 @@ }, "question": "Heeft het verkeersbord D7 () een onderbord?" }, - "12": { + "cycleway-traffic-signs-supplementary": { "mappings": { "0": { "then": "" @@ -1944,43 +2146,30 @@ }, "question": "Heeft het verkeersbord D7 () een onderbord?" }, - "13": { + "cycleways_and_roads-cycleway:buffer": { "question": "Hoe breed is de ruimte tussen het fietspad en de weg?", "render": "De schrikafstand van dit fietspad is {cycleway:buffer} m" }, - "14": { + "is lit?": { "mappings": { "0": { - "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + "then": "Deze weg is verlicht" }, "1": { - "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + "then": "Deze weg is niet verlicht" }, "2": { - "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + "then": "Deze weg is 's nachts verlicht" }, "3": { - "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + "then": "Deze weg is 24/7 verlicht" } }, - "question": "Hoe is dit fietspad gescheiden van de weg?" + "question": "Is deze weg verlicht?" }, - "15": { - "mappings": { - "0": { - "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - }, - "1": { - "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - }, - "2": { - "then": "Dit fietspad is gescheiden van de weg met parkeervakken" - }, - "3": { - "then": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - }, - "question": "Hoe is dit fietspad gescheiden van de weg?" + "width:carriageway": { + "question": "Hoe breed is de rijbaan in deze straat (in meters)?", + "render": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" } }, "title": { @@ -2012,18 +2201,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze defibrillator bevindt zich in een gebouw" - }, - "1": { - "then": "Deze defibrillator hangt buiten" - } - }, - "question": "Hangt deze defibrillator binnen of buiten?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Publiek toegankelijk" @@ -2044,7 +2222,7 @@ "question": "Is deze defibrillator vrij toegankelijk?", "render": "Toegankelijkheid is {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Dit is een manueel toestel enkel voor professionals" @@ -2056,7 +2234,42 @@ "question": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", "render": "Er is geen info over het soort toestel" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", + "render": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", + "render": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", + "render": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", + "render": "Aanvullende info: {description}" + }, + "defibrillator-email": { + "question": "Wat is het email-adres voor vragen over deze defibrillator", + "render": "Email voor vragen over deze defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", + "render": "Extra informatie voor OpenStreetMap experts: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Deze defibrillator bevindt zich in een gebouw" + }, + "1": { + "then": "Deze defibrillator hangt buiten" + } + }, + "question": "Hangt deze defibrillator binnen of buiten?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Deze defibrillator bevindt zich gelijkvloers" @@ -2068,31 +2281,7 @@ "question": "Op welke verdieping bevindt deze defibrillator zich?", "render": "De defibrillator bevindt zicht op verdieping {level}" }, - "5": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", - "render": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}" - }, - "6": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", - "render": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}" - }, - "7": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", - "render": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}" - }, - "9": { - "question": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", - "render": "Officieel identificatienummer van het toestel: {ref}" - }, - "10": { - "question": "Wat is het email-adres voor vragen over deze defibrillator", - "render": "Email voor vragen over deze defibrillator: {email}" - }, - "11": { - "question": "Wat is het telefoonnummer voor vragen over deze defibrillator", - "render": "Telefoonnummer voor vragen over deze defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 open (inclusief feestdagen)" @@ -2101,11 +2290,15 @@ "question": "Wanneer is deze defibrillator beschikbaar?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", - "render": "Aanvullende info: {description}" + "defibrillator-phone": { + "question": "Wat is het telefoonnummer voor vragen over deze defibrillator", + "render": "Telefoonnummer voor vragen over deze defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", + "render": "Officieel identificatienummer van het toestel: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Vandaag nagekeken!" @@ -2113,10 +2306,6 @@ }, "question": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", "render": "Deze defibrillator is nagekeken in OSM op {survey:date}" - }, - "15": { - "question": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", - "render": "Extra informatie voor OpenStreetMap experts: {fixme}" } }, "title": { @@ -2131,11 +2320,22 @@ "name": "Drinkbaar water", "presets": { "0": { - "title": "Drinkbaar water" + "title": "drinkbaar water" } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "Een drinkbus bijvullen gaat makkelijk" + }, + "1": { + "then": "Een drinkbus past moeilijk" + } + }, + "question": "Hoe gemakkelijk is het om drinkbussen bij te vullen?" + }, + "Still in use?": { "mappings": { "0": { "then": "Deze drinkwaterfontein werkt" @@ -2150,18 +2350,7 @@ "question": "Is deze drinkwaterkraan nog steeds werkende?", "render": "Deze waterkraan-status is {operational_status}" }, - "2": { - "mappings": { - "0": { - "then": "Een drinkbus bijvullen gaat makkelijk" - }, - "1": { - "then": "Een drinkbus past moeilijk" - } - }, - "question": "Hoe gemakkelijk is het om drinkbussen bij te vullen?" - }, - "3": { + "render-closest-drinking-water": { "render": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter" } }, @@ -2216,22 +2405,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van deze eetgelegenheid?", - "render": "De naam van deze eetgelegeheid is {name}" - }, - "2": { - "mappings": { - "0": { - "then": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" - }, - "1": { - "then": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" - } - }, - "question": "Wat voor soort zaak is dit?" - }, - "9": { + "Cuisine": { "mappings": { "0": { "then": "Dit is een pizzeria" @@ -2282,7 +2456,22 @@ "question": "Welk soort gerechten worden hier geserveerd?", "render": "Deze plaats serveert vooral {cuisine}" }, - "10": { + "Fastfood vs restaurant": { + "mappings": { + "0": { + "then": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" + }, + "1": { + "then": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" + } + }, + "question": "Wat voor soort zaak is dit?" + }, + "Name": { + "question": "Wat is de naam van deze eetgelegenheid?", + "render": "De naam van deze eetgelegeheid is {name}" + }, + "Takeaway": { "mappings": { "0": { "then": "Hier is enkel afhaal mogelijk" @@ -2296,24 +2485,7 @@ }, "question": "Biedt deze zaak een afhaalmogelijkheid aan?" }, - "11": { - "mappings": { - "0": { - "then": "Geen vegetarische opties beschikbaar" - }, - "1": { - "then": "Beperkte vegetarische opties zijn beschikbaar" - }, - "2": { - "then": "Vegetarische opties zijn beschikbaar" - }, - "3": { - "then": "Enkel vegetarische opties zijn beschikbaar" - } - }, - "question": "Heeft deze eetgelegenheid een vegetarische optie?" - }, - "12": { + "Vegan (no friture)": { "mappings": { "0": { "then": "Geen veganistische opties beschikbaar" @@ -2330,7 +2502,77 @@ }, "question": "Heeft deze eetgelegenheid een veganistische optie?" }, - "13": { + "Vegetarian (no friture)": { + "mappings": { + "0": { + "then": "Geen vegetarische opties beschikbaar" + }, + "1": { + "then": "Beperkte vegetarische opties zijn beschikbaar" + }, + "2": { + "then": "Vegetarische opties zijn beschikbaar" + }, + "3": { + "then": "Enkel vegetarische opties zijn beschikbaar" + } + }, + "question": "Heeft deze eetgelegenheid een vegetarische optie?" + }, + "friture-oil": { + "mappings": { + "0": { + "then": "Plantaardige olie" + }, + "1": { + "then": "Dierlijk vet" + } + }, + "question": "Bakt deze frituur met dierlijk vet of met plantaardige olie?" + }, + "friture-take-your-container": { + "mappings": { + "0": { + "then": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken" + }, + "1": { + "then": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen" + }, + "2": { + "then": "Je moet je eigen containers meenemen om je bestelling in mee te nemen." + } + }, + "question": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?" + }, + "friture-vegan": { + "mappings": { + "0": { + "then": "Er zijn veganistische snacks aanwezig" + }, + "1": { + "then": "Slechts enkele veganistische snacks" + }, + "2": { + "then": "Geen veganistische snacks beschikbaar" + } + }, + "question": "Heeft deze frituur veganistische snacks?" + }, + "friture-vegetarian": { + "mappings": { + "0": { + "then": "Er zijn vegetarische snacks aanwezig" + }, + "1": { + "then": "Slechts enkele vegetarische snacks" + }, + "2": { + "then": "Geen vegetarische snacks beschikbaar" + } + }, + "question": "Heeft deze frituur vegetarische snacks?" + }, + "halal (no friture)": { "mappings": { "0": { "then": "Er zijn geen halal opties aanwezig" @@ -2346,59 +2588,6 @@ } }, "question": "Heeft dit restaurant halal opties?" - }, - "14": { - "mappings": { - "0": { - "then": "Er zijn vegetarische snacks aanwezig" - }, - "1": { - "then": "Slechts enkele vegetarische snacks" - }, - "2": { - "then": "Geen vegetarische snacks beschikbaar" - } - }, - "question": "Heeft deze frituur vegetarische snacks?" - }, - "15": { - "mappings": { - "0": { - "then": "Er zijn veganistische snacks aanwezig" - }, - "1": { - "then": "Slechts enkele veganistische snacks" - }, - "2": { - "then": "Geen veganistische snacks beschikbaar" - } - }, - "question": "Heeft deze frituur veganistische snacks?" - }, - "16": { - "mappings": { - "0": { - "then": "Plantaardige olie" - }, - "1": { - "then": "Dierlijk vet" - } - }, - "question": "Bakt deze frituur met dierlijk vet of met plantaardige olie?" - }, - "17": { - "mappings": { - "0": { - "then": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken" - }, - "1": { - "then": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen" - }, - "2": { - "then": "Je moet je eigen containers meenemen om je bestelling in mee te nemen." - } - }, - "question": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?" } }, "title": { @@ -2421,10 +2610,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval." }, - "2": { + "ghost_bike-inscription": { + "question": "Wat is het opschrift op deze witte fiets?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "De naam is niet aangeduid op de fiets" @@ -2433,15 +2626,11 @@ "question": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", "render": "Ter nagedachtenis van {name}" }, - "3": { + "ghost_bike-source": { "question": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", "render": "Meer informatie" }, - "4": { - "question": "Wat is het opschrift op deze witte fiets?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Wanneer werd deze witte fiets geplaatst?", "render": "Geplaatst op {start_date}" } @@ -2470,7 +2659,7 @@ "name": "Informatieborden", "presets": { "0": { - "title": "Informatiebord" + "title": "informatiebord" } }, "title": { @@ -2487,16 +2676,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze kaart is gebaseerd op OpenStreetMap" - } - }, - "question": "Op welke data is deze kaart gebaseerd?", - "render": "Deze kaart is gebaseerd op {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" " @@ -2515,6 +2695,15 @@ } }, "question": "Is de attributie voor OpenStreetMap aanwezig?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Deze kaart is gebaseerd op OpenStreetMap" + } + }, + "question": "Op welke data is deze kaart gebaseerd?", + "render": "Deze kaart is gebaseerd op {map_source}" } }, "title": { @@ -2549,11 +2738,11 @@ "presets": { "0": { "description": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt", - "title": "Natuurreservaat" + "title": "natuurreservaat" } }, "tagRenderings": { - "1": { + "Access tag": { "mappings": { "0": { "then": "Vrij toegankelijk" @@ -2577,7 +2766,48 @@ "question": "Is dit gebied toegankelijk?", "render": "De toegankelijkheid van dit gebied is: {access:description}" }, - "2": { + "Curator": { + "question": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", + "render": "{curator} is de beheerder van dit gebied" + }, + "Dogs?": { + "mappings": { + "0": { + "then": "Honden moeten aan de leiband" + }, + "1": { + "then": "Honden zijn niet toegestaan" + }, + "2": { + "then": "Honden zijn welkom en mogen vrij rondlopen" + } + }, + "question": "Zijn honden toegelaten in dit gebied?" + }, + "Editable description {description:0}": { + "render": "Extra info: {description:0}" + }, + "Email": { + "question": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", + "render": "{email}" + }, + "Name tag": { + "mappings": { + "0": { + "then": "Dit gebied heeft geen naam" + } + }, + "question": "Wat is de naam van dit gebied?", + "render": "Dit gebied heet {name}" + }, + "Name:nl-tag": { + "question": "Wat is de Nederlandstalige naam van dit gebied?", + "render": "Dit gebied heet {name:nl}" + }, + "Non-editable description {description}": { + "render": "Extra info: {description}" + }, + "Operator tag": { "mappings": { "0": { "then": "Dit gebied wordt beheerd door Natuurpunt" @@ -2592,56 +2822,15 @@ "question": "Wie beheert dit gebied?", "render": "Beheer door {operator}" }, - "3": { - "question": "Wat is de Nederlandstalige naam van dit gebied?", - "render": "Dit gebied heet {name:nl}" + "Surface area": { + "render": "Totale oppervlakte: {_surface:ha}Ha" }, - "4": { - "mappings": { - "0": { - "then": "Dit gebied heeft geen naam" - } - }, - "question": "Wat is de naam van dit gebied?", - "render": "Dit gebied heet {name}" - }, - "5": { - "mappings": { - "0": { - "then": "Honden moeten aan de leiband" - }, - "1": { - "then": "Honden zijn niet toegestaan" - }, - "2": { - "then": "Honden zijn welkom en mogen vrij rondlopen" - } - }, - "question": "Zijn honden toegelaten in dit gebied?" - }, - "6": { + "Website": { "question": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?" }, - "7": { - "question": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", - "render": "{curator} is de beheerder van dit gebied" - }, - "8": { - "question": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", - "render": "{email}" - }, - "9": { + "phone": { "question": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", "render": "{phone}" - }, - "10": { - "render": "Extra info: {description}" - }, - "11": { - "render": "Extra info: {description:0}" - }, - "12": { - "render": "Totale oppervlakte: {_surface:ha}Ha" } }, "title": { @@ -2666,24 +2855,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze toren heeft geen specifieke naam" - } - }, - "question": "Heeft deze toren een naam?", - "render": "Deze toren heet {name}" - }, - "2": { - "question": "Hoe hoog is deze toren?", - "render": "Deze toren is {height} hoog" - }, - "3": { - "question": "Wie onderhoudt deze toren?", - "render": "Wordt onderhouden door {operator}" - }, - "5": { + "Fee": { "mappings": { "0": { "then": "Gratis te bezoeken" @@ -2691,6 +2863,23 @@ }, "question": "Hoeveel moet men betalen om deze toren te bezoeken?", "render": "Deze toren bezoeken kost {charge}" + }, + "Height": { + "question": "Hoe hoog is deze toren?", + "render": "Deze toren is {height} hoog" + }, + "Operator": { + "question": "Wie onderhoudt deze toren?", + "render": "Wordt onderhouden door {operator}" + }, + "name": { + "mappings": { + "0": { + "then": "Deze toren heeft geen specifieke naam" + } + }, + "question": "Heeft deze toren een naam?", + "render": "Deze toren heet {name}" } }, "title": { @@ -2713,49 +2902,15 @@ }, "parking": { "description": "Parking", - "name": "parking", + "name": "Parking", "presets": { "0": { - "description": "Voeg een ontbrekend, erkend pad toe.", - "title": "Paden" - } - }, - "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Vrij toegankelijk" - }, - "1": { - "then": "Niet toegankelijk" - }, - "2": { - "then": "Niet toegankelijk, want privégebied" - }, - "3": { - "then": "Toegankelijk, ondanks dat het privegebied is" - }, - "4": { - "then": "Enkel toegankelijk met een gids of tijdens een activiteit" - }, - "5": { - "then": "Toegankelijk mits betaling" - } - }, - "question": "Is dit gebied toegankelijk?", - "render": "De toegankelijkheid van dit gebied is: {access:description}" + "description": "Voeg hier een fietsenstalling toe", + "title": "fietsparking" }, - "2": { - "mappings": { - "0": { - "then": "Dit gebied wordt beheerd door Natuurpunt" - }, - "1": { - "then": "Dit gebied wordt beheerd door {operator}" - } - }, - "question": "Wie beheert dit pad?", - "render": "Beheer door {operator}" + "1": { + "description": "Voeg hier een parking voor auto's toe", + "title": "parking" } }, "title": { @@ -2778,11 +2933,11 @@ "name": "Picnictafels", "presets": { "0": { - "title": "Picnic-tafel" + "title": "picnic-tafel" } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Deze picnictafel is gemaakt uit hout" @@ -2823,7 +2978,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Geheel toegankelijk voor rolstoelgebruikers" + }, + "1": { + "then": "Beperkt toegankelijk voor rolstoelgebruikers" + }, + "2": { + "then": "Niet toegankelijk voor rolstoelgebruikers" + } + }, + "question": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Vrij toegankelijk voor het publiek" + }, + "1": { + "then": "Vrij toegankelijk voor het publiek" + }, + "2": { + "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" + }, + "3": { + "then": "Vrij toegankelijk voor scholieren van de school" + }, + "4": { + "then": "Niet vrij toegankelijk" + } + }, + "question": "Is deze speeltuin vrij toegankelijk voor het publiek?" + }, + "playground-email": { + "question": "Wie kan men emailen indien er problemen zijn met de speeltuin?", + "render": "De bevoegde dienst kan bereikt worden via {email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Deze speeltuin is 's nachts verlicht" + }, + "1": { + "then": "Deze speeltuin is 's nachts niet verlicht" + } + }, + "question": "Is deze speeltuin 's nachts verlicht?" + }, + "playground-max_age": { + "question": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", + "render": "Toegankelijk tot {max_age}" + }, + "playground-min_age": { + "question": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", + "render": "Toegankelijk vanaf {min_age} jaar oud" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Van zonsopgang tot zonsondergang" + }, + "1": { + "then": "Dag en nacht toegankelijk" + }, + "2": { + "then": "Dag en nacht toegankelijk" + } + }, + "question": "Op welke uren is deze speeltuin toegankelijk?" + }, + "playground-operator": { + "question": "Wie beheert deze speeltuin?", + "render": "Beheer door {operator}" + }, + "playground-phone": { + "question": "Wie kan men bellen indien er problemen zijn met de speeltuin?", + "render": "De bevoegde dienst kan getelefoneerd worden via {phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -2852,85 +3086,6 @@ }, "question": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", "render": "De ondergrond is {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Deze speeltuin is 's nachts verlicht" - }, - "1": { - "then": "Deze speeltuin is 's nachts niet verlicht" - } - }, - "question": "Is deze speeltuin 's nachts verlicht?" - }, - "3": { - "question": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", - "render": "Toegankelijk vanaf {min_age} jaar oud" - }, - "4": { - "question": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", - "render": "Toegankelijk tot {max_age}" - }, - "5": { - "question": "Wie beheert deze speeltuin?", - "render": "Beheer door {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Vrij toegankelijk voor het publiek" - }, - "1": { - "then": "Vrij toegankelijk voor het publiek" - }, - "2": { - "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" - }, - "3": { - "then": "Vrij toegankelijk voor scholieren van de school" - }, - "4": { - "then": "Niet vrij toegankelijk" - } - }, - "question": "Is deze speeltuin vrij toegankelijk voor het publiek?" - }, - "7": { - "question": "Wie kan men emailen indien er problemen zijn met de speeltuin?", - "render": "De bevoegde dienst kan bereikt worden via {email}" - }, - "8": { - "question": "Wie kan men bellen indien er problemen zijn met de speeltuin?", - "render": "De bevoegde dienst kan getelefoneerd worden via {phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Geheel toegankelijk voor rolstoelgebruikers" - }, - "1": { - "then": "Beperkt toegankelijk voor rolstoelgebruikers" - }, - "2": { - "then": "Niet toegankelijk voor rolstoelgebruikers" - } - }, - "question": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?" - }, - "10": { - "mappings": { - "0": { - "then": "Van zonsopgang tot zonsondergang" - }, - "1": { - "then": "Dag en nacht toegankelijk" - }, - "2": { - "then": "Dag en nacht toegankelijk" - } - }, - "question": "Op welke uren is deze speeltuin toegankelijk?" } }, "title": { @@ -2944,6 +3099,15 @@ }, "public_bookcase": { "description": "Een straatkastje met boeken voor iedereen", + "filter": { + "2": { + "options": { + "0": { + "question": "Binnen of buiten" + } + } + } + }, "name": "Boekenruilkastjes", "presets": { "0": { @@ -2951,20 +3115,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Dit boekenruilkastje heeft geen naam" - } - }, - "question": "Wat is de naam van dit boekenuilkastje?", - "render": "De naam van dit boekenruilkastje is {name}" - }, - "3": { - "question": "Hoeveel boeken passen er in dit boekenruilkastje?", - "render": "Er passen {capacity} boeken" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Voornamelijk kinderboeken" @@ -2978,7 +3129,18 @@ }, "question": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Publiek toegankelijk" + }, + "1": { + "then": "Enkel toegankelijk voor klanten" + } + }, + "question": "Is dit boekenruilkastje publiek toegankelijk?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Dit boekenruilkastje staat binnen" @@ -2992,22 +3154,7 @@ }, "question": "Staat dit boekenruilkastje binnen of buiten?" }, - "6": { - "mappings": { - "0": { - "then": "Publiek toegankelijk" - }, - "1": { - "then": "Enkel toegankelijk voor klanten" - } - }, - "question": "Is dit boekenruilkastje publiek toegankelijk?" - }, - "7": { - "question": "Wie is verantwoordelijk voor dit boekenruilkastje?", - "render": "Onderhouden door {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Deel van het netwerk 'Little Free Library'" @@ -3019,7 +3166,24 @@ "question": "Is dit boekenruilkastje deel van een netwerk?", "render": "Dit boekenruilkastje is deel van het netwerk {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Hoeveel boeken passen er in dit boekenruilkastje?", + "render": "Er passen {capacity} boeken" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Dit boekenruilkastje heeft geen naam" + } + }, + "question": "Wat is de naam van dit boekenuilkastje?", + "render": "De naam van dit boekenruilkastje is {name}" + }, + "public_bookcase-operator": { + "question": "Wie is verantwoordelijk voor dit boekenruilkastje?", + "render": "Onderhouden door {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Dit boekenruilkastje maakt geen deel uit van een netwerk" @@ -3028,11 +3192,11 @@ "question": "Wat is het referentienummer van dit boekenruilkastje?", "render": "Het referentienummer binnen {brand} is {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Op welke dag werd dit boekenruilkastje geinstalleerd?", "render": "Geplaatst op {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Is er een website over dit boekenruilkastje?", "render": "Meer info op de website" } @@ -3049,7 +3213,7 @@ "slow_roads": { "name": "Paadjes, trage wegen en autoluwe straten", "tagRenderings": { - "1": { + "explanation": { "mappings": { "1": { "then": "Dit is een brede, autovrije straat" @@ -3068,7 +3232,7 @@ } } }, - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -3132,7 +3296,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Publiek toegankelijk" + }, + "1": { + "then": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)" + }, + "2": { + "then": "Enkel toegankelijk voor leden van de bijhorende sportclub" + }, + "3": { + "then": "Privaat en niet toegankelijk" + } + }, + "question": "Is dit sportterrein publiek toegankelijk?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Reserveren is verplicht om gebruik te maken van dit sportterrein" + }, + "1": { + "then": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein" + }, + "2": { + "then": "Reserveren is mogelijk, maar geen voorwaarde" + }, + "3": { + "then": "Reserveren is niet mogelijk" + } + }, + "question": "Moet men reserveren om gebruik te maken van dit sportveld?" + }, + "sport_pitch-email": { + "question": "Wat is het email-adres van de bevoegde dienst of uitbater?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "24/7 toegankelijk" + } + }, + "question": "Wanneer is dit sportveld toegankelijk?" + }, + "sport_pitch-phone": { + "question": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Hier kan men basketbal spelen" @@ -3156,7 +3368,7 @@ "question": "Welke sporten kan men hier beoefenen?", "render": "Hier kan men {sport} beoefenen" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -3176,54 +3388,6 @@ }, "question": "Wat is de ondergrond van dit sportveld?", "render": "De ondergrond is {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Publiek toegankelijk" - }, - "1": { - "then": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)" - }, - "2": { - "then": "Enkel toegankelijk voor leden van de bijhorende sportclub" - }, - "3": { - "then": "Privaat en niet toegankelijk" - } - }, - "question": "Is dit sportterrein publiek toegankelijk?" - }, - "4": { - "mappings": { - "0": { - "then": "Reserveren is verplicht om gebruik te maken van dit sportterrein" - }, - "1": { - "then": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein" - }, - "2": { - "then": "Reserveren is mogelijk, maar geen voorwaarde" - }, - "3": { - "then": "Reserveren is niet mogelijk" - } - }, - "question": "Moet men reserveren om gebruik te maken van dit sportveld?" - }, - "5": { - "question": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?" - }, - "6": { - "question": "Wat is het email-adres van de bevoegde dienst of uitbater?" - }, - "7": { - "mappings": { - "1": { - "then": "24/7 toegankelijk" - } - }, - "question": "Wanneer is dit sportveld toegankelijk?" } }, "title": { @@ -3233,7 +3397,7 @@ "surveillance_camera": { "name": "Bewakingscamera's", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Een vaste camera" @@ -3247,34 +3411,7 @@ }, "question": "Wat voor soort camera is dit?" }, - "2": { - "mappings": { - "0": { - "then": "Filmt in kompasrichting {direction}" - } - }, - "question": "In welke geografische richting filmt deze camera?", - "render": "Filmt in kompasrichting {camera:direction}" - }, - "3": { - "question": "Wie beheert deze bewakingscamera?", - "render": "Beheer door {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel..." - }, - "1": { - "then": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)" - }, - "2": { - "then": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ..." - } - }, - "question": "Wat soort bewaking wordt hier uitgevoerd?" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Deze camera bevindt zich binnen" @@ -3288,11 +3425,29 @@ }, "question": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?" }, - "6": { + "Level": { "question": "Op welke verdieping bevindt deze camera zich?", "render": "Bevindt zich op verdieping {level}" }, - "7": { + "Operator": { + "question": "Wie beheert deze bewakingscamera?", + "render": "Beheer door {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel..." + }, + "1": { + "then": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)" + }, + "2": { + "then": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ..." + } + }, + "question": "Wat soort bewaking wordt hier uitgevoerd?" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Bewaakt een parking" @@ -3316,7 +3471,7 @@ "question": "Wat wordt hier precies bewaakt?", "render": "Bewaakt een {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Deze camera hangt aan een muur" @@ -3330,6 +3485,15 @@ }, "question": "Hoe is deze camera geplaatst?", "render": "Montage: {camera:mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Filmt in kompasrichting {direction}" + } + }, + "question": "In welke geografische richting filmt deze camera?", + "render": "Filmt in kompasrichting {camera:direction}" } }, "title": { @@ -3341,15 +3505,15 @@ "presets": { "0": { "description": "Een publieke toilet", - "title": "Toilet" + "title": "toilet" }, "1": { "description": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", - "title": "Een rolstoeltoegankelijke toilet" + "title": "een rolstoeltoegankelijke toilet" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Publiek toegankelijk" @@ -3370,61 +3534,7 @@ "question": "Zijn deze toiletten publiek toegankelijk?", "render": "Toegankelijkheid is {access}" }, - "2": { - "mappings": { - "0": { - "then": "Men moet betalen om deze toiletten te gebruiken" - }, - "1": { - "then": "Gratis te gebruiken" - } - }, - "question": "Zijn deze toiletten gratis te gebruiken?" - }, - "3": { - "question": "Hoeveel moet men betalen om deze toiletten te gebruiken?", - "render": "De toiletten gebruiken kost {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Er is een toilet voor rolstoelgebruikers" - }, - "1": { - "then": "Niet toegankelijk voor rolstoelgebruikers" - } - }, - "question": "Is er een rolstoeltoegankelijke toilet voorzien?" - }, - "5": { - "mappings": { - "0": { - "then": "Er zijn enkel WC's om op te zitten" - }, - "1": { - "then": "Er zijn enkel urinoirs" - }, - "2": { - "then": "Er zijn enkel hurktoiletten" - }, - "3": { - "then": "Er zijn zowel urinoirs als zittoiletten" - } - }, - "question": "Welke toiletten zijn dit?" - }, - "6": { - "mappings": { - "0": { - "then": "Er is een luiertafel" - }, - "1": { - "then": "Geen luiertafel" - } - }, - "question": "Is er een luiertafel beschikbaar?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "De luiertafel bevindt zich in de vrouwentoiletten " @@ -3441,6 +3551,82 @@ }, "question": "Waar bevindt de luiertafel zich?", "render": "De luiertafel bevindt zich in {changing_table:location}" + }, + "toilet-charge": { + "question": "Hoeveel moet men betalen om deze toiletten te gebruiken?", + "render": "De toiletten gebruiken kost {charge}" + }, + "toilet-handwashing": { + "mappings": { + "0": { + "then": "Deze toiletten hebben een lavabo waar men de handen kan wassen" + }, + "1": { + "then": "Deze toiletten hebben geen lavabo waar men de handen kan wassen" + } + }, + "question": "Hebben deze toiletten een lavabo om de handen te wassen?" + }, + "toilet-has-paper": { + "mappings": { + "0": { + "then": "Deze toilet is voorzien van toiletpapier" + }, + "1": { + "then": "Je moet je eigen toiletpapier meebrengen naar deze toilet" + } + }, + "question": "Moet je je eigen toiletpappier meenemen naar deze toilet?" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Er is een luiertafel" + }, + "1": { + "then": "Geen luiertafel" + } + }, + "question": "Is er een luiertafel beschikbaar?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Men moet betalen om deze toiletten te gebruiken" + }, + "1": { + "then": "Gratis te gebruiken" + } + }, + "question": "Zijn deze toiletten gratis te gebruiken?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Er zijn enkel WC's om op te zitten" + }, + "1": { + "then": "Er zijn enkel urinoirs" + }, + "2": { + "then": "Er zijn enkel hurktoiletten" + }, + "3": { + "then": "Er zijn zowel urinoirs als zittoiletten" + } + }, + "question": "Welke toiletten zijn dit?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Er is een toilet voor rolstoelgebruikers" + }, + "1": { + "then": "Niet toegankelijk voor rolstoelgebruikers" + } + }, + "question": "Is er een rolstoeltoegankelijke toilet voorzien?" } }, "title": { @@ -3451,26 +3637,7 @@ "description": "Aangeduide wandeltochten", "name": "Wandeltochten", "tagRenderings": { - "1": { - "render": "Deze wandeling is {_length:km} kilometer lang" - }, - "2": { - "question": "Wat is de naam van deze wandeling?", - "render": "Deze wandeling heet {name}" - }, - "3": { - "mappings": { - "0": { - "then": "Dit gebied wordt beheerd door Natuurpunt" - }, - "1": { - "then": "Dit gebied wordt beheerd door {operator}" - } - }, - "question": "Wie beheert deze wandeltocht?", - "render": "Beheer door {operator}" - }, - "4": { + "Color": { "mappings": { "0": { "then": "Blauwe wandeling" @@ -3488,7 +3655,23 @@ "question": "Welke kleur heeft deze wandeling?", "render": "Deze wandeling heeft kleur {colour}" }, - "5": { + "Name": { + "question": "Wat is de naam van deze wandeling?", + "render": "Deze wandeling heet {name}" + }, + "Operator tag": { + "mappings": { + "0": { + "then": "Dit gebied wordt beheerd door Natuurpunt" + }, + "1": { + "then": "Dit gebied wordt beheerd door {operator}" + } + }, + "question": "Wie beheert deze wandeltocht?", + "render": "Beheer door {operator}" + }, + "Wheelchair access": { "mappings": { "0": { "then": "deze wandeltocht is toegankelijk met de rolstoel" @@ -3499,7 +3682,7 @@ }, "question": "Is deze wandeling toegankelijk met de rolstoel?" }, - "6": { + "pushchair access": { "mappings": { "0": { "then": "deze wandeltocht is toegankelijk met de buggy" @@ -3509,6 +3692,9 @@ } }, "question": "Is deze wandeltocht toegankelijk met de buggy?" + }, + "trail-length": { + "render": "Deze wandeling is {_length:km} kilometer lang" } }, "title": { @@ -3532,29 +3718,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Hoogte: {height} m" - } - }, - "render": "Hoogte: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Loofboom" + "then": "Bladverliezend: de boom is een periode van het jaar kaal." }, "1": { - "then": "\"\"/ Naaldboom" - }, - "2": { - "then": "\"\"/ Permanent bladloos" + "then": "Groenblijvend." } }, - "question": "Is dit een naald- of loofboom?" + "question": "Is deze boom groenblijvend of bladverliezend?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie." @@ -3583,27 +3758,15 @@ }, "question": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Bladverliezend: de boom is een periode van het jaar kaal." - }, - "1": { - "then": "Groenblijvend." + "then": "Hoogte: {height} m" } }, - "question": "Is deze boom groenblijvend of bladverliezend?" + "render": "Hoogte: {height}" }, - "5": { - "mappings": { - "0": { - "then": "De boom heeft geen naam." - } - }, - "question": "Heeft de boom een naam?", - "render": "Naam: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen" @@ -3623,11 +3786,34 @@ }, "question": "Is deze boom erkend als erfgoed?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Loofboom" + }, + "1": { + "then": "\"\"/ Naaldboom" + }, + "2": { + "then": "\"\"/ Permanent bladloos" + } + }, + "question": "Is dit een naald- of loofboom?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "De boom heeft geen naam." + } + }, + "question": "Heeft de boom een naam?", + "render": "Naam: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", "render": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Wat is het Wikidata-ID van deze boom?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -3650,7 +3836,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Zijn er bijzonderheden die je wilt toevoegen?" } }, @@ -3700,7 +3886,7 @@ } }, "tagRenderings": { - "0": { + "waste-basket-waste-types": { "mappings": { "0": { "then": "Een vuilnisbak voor zwerfvuil" @@ -3730,9 +3916,9 @@ }, "watermill": { "description": "Watermolens", - "name": "watermolens", + "name": "Watermolens", "tagRenderings": { - "1": { + "Access tag": { "mappings": { "0": { "then": "Vrij toegankelijk" @@ -3756,7 +3942,7 @@ "question": "Is dit gebied toegankelijk?", "render": "De toegankelijkheid van dit gebied is: {access:description}" }, - "2": { + "Operator tag": { "mappings": { "0": { "then": "Dit gebied wordt beheerd door Natuurpunt" diff --git a/langs/layers/pl.json b/langs/layers/pl.json index 682a45333..64b52a16b 100644 --- a/langs/layers/pl.json +++ b/langs/layers/pl.json @@ -3,12 +3,11 @@ "name": "Ławki", "presets": { "0": { - "description": "Dodaj nową ławkę", "title": "Ławka" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Oparcie: Tak" @@ -20,39 +19,7 @@ "question": "Czy ta ławka ma oparcie?", "render": "Oparcie" }, - "2": { - "question": "Ile siedzeń ma ta ławka?", - "render": "{seats} siedzeń" - }, - "3": { - "mappings": { - "0": { - "then": "Materiał: drewno" - }, - "1": { - "then": "Materiał: metal" - }, - "2": { - "then": "Materiał: kamień" - }, - "3": { - "then": "Materiał: beton" - }, - "4": { - "then": "Materiał: plastik" - }, - "5": { - "then": "Materiał: stal" - } - }, - "question": "Z czego wykonana jest ławka (siedzisko)?", - "render": "Materiał: {material}" - }, - "4": { - "question": "W jakim kierunku patrzysz siedząc na ławce?", - "render": "Siedząc na ławce, patrzy się w kierunku {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Kolor: brązowy" @@ -82,7 +49,39 @@ "question": "Jaki kolor ma ta ławka?", "render": "Kolor: {colour}" }, - "6": { + "bench-direction": { + "question": "W jakim kierunku patrzysz siedząc na ławce?", + "render": "Siedząc na ławce, patrzy się w kierunku {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiał: drewno" + }, + "1": { + "then": "Materiał: metal" + }, + "2": { + "then": "Materiał: kamień" + }, + "3": { + "then": "Materiał: beton" + }, + "4": { + "then": "Materiał: plastik" + }, + "5": { + "then": "Materiał: stal" + } + }, + "question": "Z czego wykonana jest ławka (siedzisko)?", + "render": "Materiał: {material}" + }, + "bench-seats": { + "question": "Ile siedzeń ma ta ławka?", + "render": "{seats} siedzeń" + }, + "bench-survey:date": { "question": "Kiedy ostatnio badano tę ławkę?", "render": "Ławka ta była ostatnio badana w dniu {survey:date}" } @@ -94,7 +93,7 @@ "bench_at_pt": { "name": "Ławki na przystankach komunikacji miejskiej", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -110,18 +109,6 @@ "bicycle_library": { "description": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" }, - "bike_monitoring_station": { - "title": { - "mappings": { - "0": { - "then": "Stacja liczenia rowerów {name}" - }, - "1": { - "then": "Stacja liczenia rowerów {ref}" - } - } - } - }, "bike_parking": { "name": "Parking dla rowerów", "presets": { @@ -130,11 +117,11 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "question": "Jaki jest typ tego parkingu dla rowerów?", "render": "Jest to parking rowerowy typu: {bicycle_parking}" }, - "2": { + "Underground?": { "question": "Jaka jest względna lokalizacja tego parkingu rowerowego?" } }, @@ -153,7 +140,7 @@ } }, "tagRenderings": { - "8": { + "Operational status": { "mappings": { "0": { "then": "Pompka rowerowa jest zepsuta" @@ -164,11 +151,7 @@ }, "question": "Czy pompka rowerowa jest nadal sprawna?" }, - "10": { - "question": "Jakie zawory są obsługiwane?", - "render": "Ta pompka obsługuje następujące zawory: {valves}" - }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Pompa ręczna" @@ -179,7 +162,7 @@ }, "question": "Czy jest to elektryczna pompka do roweru?" }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Jest manometr" @@ -192,6 +175,10 @@ } }, "question": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" + }, + "bike_repair_station-valves": { + "question": "Jakie zawory są obsługiwane?", + "render": "Ta pompka obsługuje następujące zawory: {valves}" } } }, diff --git a/langs/layers/pt_BR.json b/langs/layers/pt_BR.json index 835527f4b..923a5d76d 100644 --- a/langs/layers/pt_BR.json +++ b/langs/layers/pt_BR.json @@ -3,12 +3,11 @@ "name": "Bancos", "presets": { "0": { - "description": "Adicionar um novo banco", - "title": "Banco" + "title": "banco" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Encosto: Sim" @@ -20,39 +19,7 @@ "question": "Este assento tem um escosto?", "render": "Encosto" }, - "2": { - "question": "Quantos assentos este banco tem?", - "render": "{seats} assentos" - }, - "3": { - "mappings": { - "0": { - "then": "Material: madeira" - }, - "1": { - "then": "Material: metal" - }, - "2": { - "then": "Material: pedra" - }, - "3": { - "then": "Material: concreto" - }, - "4": { - "then": "Material: plástico" - }, - "5": { - "then": "Material: aço" - } - }, - "question": "De que é feito o banco (assento)?", - "render": "Material: {material}" - }, - "4": { - "question": "Em que direção você olha quando está sentado no banco?", - "render": "Ao sentar-se no banco, olha-se para {direction} °." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Cor: marrom" @@ -82,7 +49,39 @@ "question": "Qual a cor dessa bancada?", "render": "Cor: {colour}" }, - "6": { + "bench-direction": { + "question": "Em que direção você olha quando está sentado no banco?", + "render": "Ao sentar-se no banco, olha-se para {direction} °." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: madeira" + }, + "1": { + "then": "Material: metal" + }, + "2": { + "then": "Material: pedra" + }, + "3": { + "then": "Material: concreto" + }, + "4": { + "then": "Material: plástico" + }, + "5": { + "then": "Material: aço" + } + }, + "question": "De que é feito o banco (assento)?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "Quantos assentos este banco tem?", + "render": "{seats} assentos" + }, + "bench-survey:date": { "question": "Quando esta bancada foi pesquisada pela última vez?", "render": "Esta bancada foi pesquisada pela última vez em {survey:date}" } @@ -94,7 +93,7 @@ "bench_at_pt": { "name": "Bancos em pontos de transporte público", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -119,23 +118,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual o nome desta biblioteca de bicicleta?", - "render": "Esta biblioteca de bicicleta é chamada de {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Emprestar uma bicicleta é grátis" - }, - "1": { - "then": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" - } - }, - "question": "Quanto custa um empréstimo de bicicleta?", - "render": "Custos de empréstimo de bicicleta {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Bicicletas para crianças disponíveis" @@ -148,6 +131,22 @@ } }, "question": "Quem pode emprestar bicicletas aqui?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Emprestar uma bicicleta é grátis" + }, + "1": { + "then": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" + } + }, + "question": "Quanto custa um empréstimo de bicicleta?", + "render": "Custos de empréstimo de bicicleta {charge}" + }, + "bicycle_library-name": { + "question": "Qual o nome desta biblioteca de bicicleta?", + "render": "Esta biblioteca de bicicleta é chamada de {name}" } }, "title": { @@ -162,7 +161,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Esta máquina de venda automática funciona" @@ -190,22 +189,20 @@ } }, "tagRenderings": { - "1": { + "bike_cafe-email": { + "question": "Qual o endereço de email de {name}?" + }, + "bike_cafe-name": { "question": "Qual o nome deste café de bicicleta?", "render": "Este café de bicicleta se chama {name}" }, - "3": { - "mappings": { - "0": { - "then": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" - }, - "1": { - "then": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" - } - }, - "question": "Há ferramentas aqui para consertar sua bicicleta?" + "bike_cafe-opening_hours": { + "question": "Quando este café de bicicleta abre?" }, - "4": { + "bike_cafe-phone": { + "question": "Qual o número de telefone de {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Este café de bicicleta conserta bicicletas" @@ -216,17 +213,19 @@ }, "question": "Este café de bicicleta conserta bicicletas?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" + }, + "1": { + "then": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" + } + }, + "question": "Há ferramentas aqui para consertar sua bicicleta?" + }, + "bike_cafe-website": { "question": "Qual o website de {name}?" - }, - "6": { - "question": "Qual o número de telefone de {name}?" - }, - "7": { - "question": "Qual o endereço de email de {name}?" - }, - "8": { - "question": "Quando este café de bicicleta abre?" } }, "title": { @@ -254,20 +253,6 @@ "render": "Serviço de limpeza de bicicletas" } }, - "bike_monitoring_station": { - "name": "Estações de monitoramento", - "title": { - "mappings": { - "0": { - "then": "Estação de contagem de bicicletas {name}" - }, - "1": { - "then": "Estação de contagem de bicicletas {ref}" - } - }, - "render": "Estação de contagem de bicicletas" - } - }, "bike_parking": { "name": "Estacionamento de bicicletas", "presets": { @@ -276,11 +261,58 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Acessível ao público" + }, + "1": { + "then": "Acesso é principalmente para visitantes de uma empresa" + }, + "2": { + "then": "Acesso é limitado aos membros de uma escola, companhia ou organização" + } + }, + "question": "Quem pode usar este estacionamento de bicicletas?", + "render": "{access}" + }, + "Bicycle parking type": { "question": "Qual o tipo deste estacionamento de bicicletas?", "render": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" }, - "2": { + "Capacity": { + "render": "Lugar para {capacity} bicicletas" + }, + "Cargo bike capacity?": { + "question": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?", + "render": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Este estacionamento tem vagas para bicicletas de carga" + }, + "1": { + "then": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." + }, + "2": { + "then": "Você não tem permissão para estacionar bicicletas de carga" + } + }, + "question": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Este estacionamento é coberto (tem um telhado)" + }, + "1": { + "then": "Este estacionamento não é coberto" + } + }, + "question": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." + }, + "Underground?": { "mappings": { "0": { "then": "Estacionamento subterrâneo" @@ -299,53 +331,6 @@ } }, "question": "Qual a localização relativa deste estacionamento de bicicletas?" - }, - "3": { - "mappings": { - "0": { - "then": "Este estacionamento é coberto (tem um telhado)" - }, - "1": { - "then": "Este estacionamento não é coberto" - } - }, - "question": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." - }, - "4": { - "render": "Lugar para {capacity} bicicletas" - }, - "5": { - "mappings": { - "0": { - "then": "Acessível ao público" - }, - "1": { - "then": "Acesso é principalmente para visitantes de uma empresa" - }, - "2": { - "then": "Acesso é limitado aos membros de uma escola, companhia ou organização" - } - }, - "question": "Quem pode usar este estacionamento de bicicletas?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Este estacionamento tem vagas para bicicletas de carga" - }, - "1": { - "then": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." - }, - "2": { - "then": "Você não tem permissão para estacionar bicicletas de carga" - } - }, - "question": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" - }, - "7": { - "question": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?", - "render": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" } }, "title": { @@ -364,7 +349,7 @@ } }, "tagRenderings": { - "1": { + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Há somente uma bomba presente" @@ -378,21 +363,7 @@ }, "question": "Quais serviços estão disponíveis nesta estação de bicicletas?" }, - "2": { - "question": "Quem faz a manutenção desta bomba de ciclo?", - "render": "Mantida por {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Sempre aberto" - }, - "1": { - "then": "Sempre aberto" - } - } - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Há uma ferramenta de corrente" @@ -402,7 +373,7 @@ } } }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Há um gancho ou um suporte" @@ -412,7 +383,7 @@ } } }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Bomba manual" @@ -422,7 +393,7 @@ } } }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Há um manômetro" @@ -434,6 +405,20 @@ "then": "Há um manômetro mas está quebrado" } } + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Sempre aberto" + }, + "1": { + "then": "Sempre aberto" + } + } + }, + "bike_repair_station-operator": { + "question": "Quem faz a manutenção desta bomba de ciclo?", + "render": "Mantida por {operator}" } }, "title": { @@ -461,34 +446,18 @@ "description": "Uma loja que vende especificamente bicicletas ou itens relacionados", "name": "Reparo/loja de bicicletas", "tagRenderings": { - "1": { - "render": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" - }, - "2": { - "question": "Qual o nome desta loja de bicicletas?", - "render": "Esta loja de bicicletas se chama {nome}" - }, - "3": { - "question": "Qual o website de {name}?" - }, - "4": { - "question": "Qual o número de telefone de {name}?" - }, - "5": { - "question": "Qual o endereço de email de {name}?" - }, - "9": { + "bike_repair_rents-bikes": { "mappings": { "0": { - "then": "Esta loja vende bicicletas" + "then": "Esta loja aluga bicicletas" }, "1": { - "then": "Esta loja não vende bicicletas" + "then": "Esta loja não aluga bicicletas" } }, - "question": "Esta loja vende bicicletas?" + "question": "Esta loja aluga bicicletas?" }, - "10": { + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Esta loja conserta bicicletas" @@ -505,16 +474,32 @@ }, "question": "Esta loja conserta bicicletas?" }, - "11": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Esta loja aluga bicicletas" + "then": "Esta loja vende bicicletas" }, "1": { - "then": "Esta loja não aluga bicicletas" + "then": "Esta loja não vende bicicletas" } }, - "question": "Esta loja aluga bicicletas?" + "question": "Esta loja vende bicicletas?" + }, + "bike_shop-email": { + "question": "Qual o endereço de email de {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" + }, + "bike_shop-name": { + "question": "Qual o nome desta loja de bicicletas?", + "render": "Esta loja de bicicletas se chama {nome}" + }, + "bike_shop-phone": { + "question": "Qual o número de telefone de {name}?" + }, + "bike_shop-website": { + "question": "Qual o website de {name}?" } }, "title": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 8993b6f05..4e776b452 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -3,12 +3,11 @@ "name": "Скамейки", "presets": { "0": { - "description": "Добавить новую скамейку", "title": "Скамейка" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Со спинкой" @@ -20,39 +19,7 @@ "question": "Есть ли у этой скамейки спинка?", "render": "Спинка" }, - "2": { - "question": "Сколько мест на этой скамейке?", - "render": "{seats} мест" - }, - "3": { - "mappings": { - "0": { - "then": "Материал: дерево" - }, - "1": { - "then": "Материал: металл" - }, - "2": { - "then": "Материал: камень" - }, - "3": { - "then": "Материал: бетон" - }, - "4": { - "then": "Материал: пластик" - }, - "5": { - "then": "Материал: сталь" - } - }, - "question": "Из какого материала сделана скамейка?", - "render": "Материал: {material}" - }, - "4": { - "question": "В каком направлении вы смотрите, когда сидите на скамейке?", - "render": "Сидя на скамейке, вы смотрите в сторону {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Цвет: коричневый" @@ -82,7 +49,39 @@ "question": "Какого цвета скамейка?", "render": "Цвет: {colour}" }, - "6": { + "bench-direction": { + "question": "В каком направлении вы смотрите, когда сидите на скамейке?", + "render": "Сидя на скамейке, вы смотрите в сторону {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Материал: дерево" + }, + "1": { + "then": "Материал: металл" + }, + "2": { + "then": "Материал: камень" + }, + "3": { + "then": "Материал: бетон" + }, + "4": { + "then": "Материал: пластик" + }, + "5": { + "then": "Материал: сталь" + } + }, + "question": "Из какого материала сделана скамейка?", + "render": "Материал: {material}" + }, + "bench-seats": { + "question": "Сколько мест на этой скамейке?", + "render": "{seats} мест" + }, + "bench-survey:date": { "question": "Когда последний раз обследовали эту скамейку?", "render": "Последний раз обследование этой скамейки проводилось {survey:date}" } @@ -94,11 +93,11 @@ "bench_at_pt": { "name": "Скамейки на остановках общественного транспорта", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Встаньте на скамейке" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +122,7 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется эта велосипедная библиотека?", - "render": "Эта велосипедная библиотека называется {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Прокат велосипедов бесплатен" - }, - "1": { - "then": "Прокат велосипеда стоит €20/год и €20 залог" - } - }, - "question": "Сколько стоит прокат велосипеда?", - "render": "Стоимость аренды велосипеда {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Доступны детские велосипеды" @@ -152,6 +135,22 @@ } }, "question": "Кто здесь может арендовать велосипед?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Прокат велосипедов бесплатен" + }, + "1": { + "then": "Прокат велосипеда стоит €20/год и €20 залог" + } + }, + "question": "Сколько стоит прокат велосипеда?", + "render": "Стоимость аренды велосипеда {charge}" + }, + "bicycle_library-name": { + "question": "Как называется эта велосипедная библиотека?", + "render": "Эта велосипедная библиотека называется {name}" } }, "title": { @@ -166,7 +165,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Этот торговый автомат работает" @@ -194,11 +193,7 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется это байк-кафе?", - "render": "Это велосипедное кафе называется {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" @@ -209,18 +204,20 @@ }, "question": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?" }, - "3": { - "mappings": { - "0": { - "then": "В этом велосипедном кафе есть инструменты для починки своего велосипеда" - }, - "1": { - "then": "В этом велосипедном кафе нет инструментов для починки своего велосипеда" - } - }, - "question": "Есть ли здесь инструменты для починки вашего велосипеда?" + "bike_cafe-email": { + "question": "Какой адрес электронной почты у {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Как называется это байк-кафе?", + "render": "Это велосипедное кафе называется {name}" + }, + "bike_cafe-opening_hours": { + "question": "Каков режим работы этого велосипедного кафе?" + }, + "bike_cafe-phone": { + "question": "Какой номер телефона у {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "В этом велосипедном кафе есть услуги ремонта велосипедов" @@ -231,17 +228,19 @@ }, "question": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "В этом велосипедном кафе есть инструменты для починки своего велосипеда" + }, + "1": { + "then": "В этом велосипедном кафе нет инструментов для починки своего велосипеда" + } + }, + "question": "Есть ли здесь инструменты для починки вашего велосипеда?" + }, + "bike_cafe-website": { "question": "Какой сайт у {name}?" - }, - "6": { - "question": "Какой номер телефона у {name}?" - }, - "7": { - "question": "Какой адрес электронной почты у {name}?" - }, - "8": { - "question": "Каков режим работы этого велосипедного кафе?" } }, "title": { @@ -253,9 +252,6 @@ "render": "Велосипедное кафе" } }, - "bike_monitoring_station": { - "name": "Станции мониторинга" - }, "bike_parking": { "name": "Велопарковка", "presets": { @@ -264,7 +260,11 @@ } }, "tagRenderings": { - "1": { + "Access": { + "question": "Кто может пользоваться этой велопарковкой?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "3": { "then": "Стойка " @@ -279,7 +279,20 @@ "question": "К какому типу относится эта велопарковка?", "render": "Это велопарковка типа {bicycle_parking}" }, - "2": { + "Capacity": { + "render": "Место для {capacity} велосипеда(ов)" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Это крытая парковка (есть крыша/навес)" + }, + "1": { + "then": "Это открытая парковка" + } + } + }, + "Underground?": { "mappings": { "0": { "then": "Подземная парковка" @@ -291,23 +304,6 @@ "then": "Парковка на крыше" } } - }, - "3": { - "mappings": { - "0": { - "then": "Это крытая парковка (есть крыша/навес)" - }, - "1": { - "then": "Это открытая парковка" - } - } - }, - "4": { - "render": "Место для {capacity} велосипеда(ов)" - }, - "5": { - "question": "Кто может пользоваться этой велопарковкой?", - "render": "{access}" } }, "title": { @@ -324,15 +320,7 @@ } }, "tagRenderings": { - "5": { - "mappings": { - "0": { - "then": "Всегда открыто" - } - }, - "question": "Когда работает эта точка обслуживания велосипедов?" - }, - "8": { + "Operational status": { "mappings": { "0": { "then": "Велосипедный насос сломан" @@ -343,18 +331,7 @@ }, "question": "Велосипедный насос все еще работает?" }, - "10": { - "mappings": { - "0": { - "then": "Клапан Presta (также известный как французский клапан)" - }, - "1": { - "then": "Клапан Dunlop" - } - }, - "render": "Этот насос поддерживает следующие клапаны: {valves}" - }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Ручной насос" @@ -365,7 +342,7 @@ }, "question": "Это электрический велосипедный насос?" }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Есть манометр" @@ -377,6 +354,25 @@ "then": "Есть манометр, но он сломан" } } + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Всегда открыто" + } + }, + "question": "Когда работает эта точка обслуживания велосипедов?" + }, + "bike_repair_station-valves": { + "mappings": { + "0": { + "then": "Клапан Presta (также известный как французский клапан)" + }, + "1": { + "then": "Клапан Dunlop" + } + }, + "render": "Этот насос поддерживает следующие клапаны: {valves}" } }, "title": { @@ -402,31 +398,40 @@ } }, "tagRenderings": { - "2": { - "question": "Как называется магазин велосипедов?", - "render": "Этот магазин велосипедов называется {name}" - }, - "3": { - "question": "Какой сайт у {name}?" - }, - "4": { - "question": "Какой номер телефона у {name}?" - }, - "5": { - "question": "Какой адрес электронной почты у {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "В этом магазине продаются велосипеды" + "then": "В этом магазине есть велосипедный насос для всеобщего пользования" }, "1": { - "then": "В этом магазине не продают велосипеды" + "then": "В этом магазине нет велосипедного насоса для всеобщего пользования" } }, - "question": "Продаются ли велосипеды в этом магазине?" + "question": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "В этом магазине оказываются услуги мойки/чистки велосипедов" + }, + "2": { + "then": "В этом магазине нет услуг мойки/чистки велосипедов" + } + }, + "question": "Здесь моют велосипеды?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Этот магазин сдает велосипеды в аренду" + }, + "1": { + "then": "Этот магазин не сдает велосипеды напрокат" + } + }, + "question": "Этот магазин сдает велосипеды в аренду?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Этот магазин ремонтирует велосипеды" @@ -443,18 +448,7 @@ }, "question": "В этом магазине ремонтируют велосипеды?" }, - "11": { - "mappings": { - "0": { - "then": "Этот магазин сдает велосипеды в аренду" - }, - "1": { - "then": "Этот магазин не сдает велосипеды напрокат" - } - }, - "question": "Этот магазин сдает велосипеды в аренду?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "В этом магазине продаются подержанные велосипеды" @@ -468,18 +462,18 @@ }, "question": "В этом магазине продаются подержанные велосипеды?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "В этом магазине есть велосипедный насос для всеобщего пользования" + "then": "В этом магазине продаются велосипеды" }, "1": { - "then": "В этом магазине нет велосипедного насоса для всеобщего пользования" + "then": "В этом магазине не продают велосипеды" } }, - "question": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" + "question": "Продаются ли велосипеды в этом магазине?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "2": { "then": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" @@ -487,16 +481,18 @@ }, "question": "Есть ли здесь инструменты для починки собственного велосипеда?" }, - "15": { - "mappings": { - "0": { - "then": "В этом магазине оказываются услуги мойки/чистки велосипедов" - }, - "2": { - "then": "В этом магазине нет услуг мойки/чистки велосипедов" - } - }, - "question": "Здесь моют велосипеды?" + "bike_shop-email": { + "question": "Какой адрес электронной почты у {name}?" + }, + "bike_shop-name": { + "question": "Как называется магазин велосипедов?", + "render": "Этот магазин велосипедов называется {name}" + }, + "bike_shop-phone": { + "question": "Какой номер телефона у {name}?" + }, + "bike_shop-website": { + "question": "Какой сайт у {name}?" } }, "title": { @@ -521,12 +517,12 @@ "description": "Зарядная станция", "name": "Зарядные станции", "tagRenderings": { - "41": { - "question": "В какое время работает эта зарядная станция?" - }, - "42": { + "Auth phone": { "question": "К какой сети относится эта станция?", "render": "{network}" + }, + "Authentication": { + "question": "В какое время работает эта зарядная станция?" } }, "title": { @@ -548,7 +544,7 @@ } }, "tagRenderings": { - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Общедоступный" @@ -561,29 +557,29 @@ } } }, - "3": { + "defibrillator-defibrillator": { "mappings": { "1": { "then": "Это обычный автоматический дефибриллятор" } } }, - "12": { + "defibrillator-description": { + "render": "Дополнительная информация: {description}" + }, + "defibrillator-fixme": { + "render": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" + }, + "defibrillator-opening_hours": { "question": "В какое время доступен этот дефибриллятор?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "render": "Дополнительная информация: {description}" - }, - "14": { + "defibrillator-survey:date": { "mappings": { "0": { "then": "Проверено сегодня!" } } - }, - "15": { - "render": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" } }, "title": { @@ -606,7 +602,7 @@ }, "food": { "tagRenderings": { - "17": { + "friture-take-your-container": { "mappings": { "1": { "then": "Приносить свою тару не разрешено" @@ -618,16 +614,16 @@ "ghost_bike": { "name": "Велосипед Ghost", "tagRenderings": { - "2": { - "render": "В знак памяти о {name}" - }, - "3": { - "render": "Доступна более подробная информация" - }, - "4": { + "ghost_bike-inscription": { "render": "{inscription}" }, - "5": { + "ghost_bike-name": { + "render": "В знак памяти о {name}" + }, + "ghost_bike-source": { + "render": "Доступна более подробная информация" + }, + "ghost_bike-start_date": { "render": "Установлен {start_date}" } }, @@ -654,7 +650,7 @@ } }, "tagRenderings": { - "1": { + "map-map_source": { "mappings": { "0": { "then": "Эта карта основана на OpenStreetMap" @@ -669,10 +665,10 @@ }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } @@ -686,7 +682,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Это деревянный стол для пикника" @@ -712,7 +708,66 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Полностью доступна пользователям кресел-колясок" + }, + "1": { + "then": "Частично доступна пользователям кресел-колясок" + }, + "2": { + "then": "Недоступна пользователям кресел-колясок" + } + }, + "question": "Доступна ли детская площадка пользователям кресел-колясок?" + }, + "playground-access": { + "mappings": { + "4": { + "then": "Недоступно" + } + } + }, + "playground-email": { + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Эта детская площадка освещается ночью" + }, + "1": { + "then": "Эта детская площадка не освещается ночью" + } + }, + "question": "Эта игровая площадка освещается ночью?" + }, + "playground-max_age": { + "render": "Доступно детям до {max_age}" + }, + "playground-min_age": { + "question": "С какого возраста доступна эта детская площадка?", + "render": "Доступно для детей старше {min_age} лет" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Открыто от рассвета до заката" + }, + "1": { + "then": "Всегда доступен" + }, + "2": { + "then": "Всегда доступен" + } + }, + "question": "Когда открыта эта игровая площадка?" + }, + "playground-phone": { + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -734,65 +789,6 @@ } }, "render": "Поверхность - {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Эта детская площадка освещается ночью" - }, - "1": { - "then": "Эта детская площадка не освещается ночью" - } - }, - "question": "Эта игровая площадка освещается ночью?" - }, - "3": { - "question": "С какого возраста доступна эта детская площадка?", - "render": "Доступно для детей старше {min_age} лет" - }, - "4": { - "render": "Доступно детям до {max_age}" - }, - "6": { - "mappings": { - "4": { - "then": "Недоступно" - } - } - }, - "7": { - "render": "{email}" - }, - "8": { - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Полностью доступна пользователям кресел-колясок" - }, - "1": { - "then": "Частично доступна пользователям кресел-колясок" - }, - "2": { - "then": "Недоступна пользователям кресел-колясок" - } - }, - "question": "Доступна ли детская площадка пользователям кресел-колясок?" - }, - "10": { - "mappings": { - "0": { - "then": "Открыто от рассвета до заката" - }, - "1": { - "then": "Всегда доступен" - }, - "2": { - "then": "Всегда доступен" - } - }, - "question": "Когда открыта эта игровая площадка?" } }, "title": { @@ -813,20 +809,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "У этого книжного шкафа нет названия" - } - }, - "question": "Как называется этот общественный книжный шкаф?", - "render": "Название книжного шкафа — {name}" - }, - "3": { - "question": "Сколько книг помещается в этом общественном книжном шкафу?", - "render": "{capacity} книг помещается в этот книжный шкаф" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "В основном детские книги" @@ -840,7 +823,7 @@ }, "question": "Какие книги можно найти в этом общественном книжном шкафу?" }, - "6": { + "bookcase-is-accessible": { "mappings": { "0": { "then": "Свободный доступ" @@ -848,11 +831,24 @@ }, "question": "Имеется ли свободный доступ к этому общественному книжному шкафу?" }, - "10": { + "public_bookcase-capacity": { + "question": "Сколько книг помещается в этом общественном книжном шкафу?", + "render": "{capacity} книг помещается в этот книжный шкаф" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "У этого книжного шкафа нет названия" + } + }, + "question": "Как называется этот общественный книжный шкаф?", + "render": "Название книжного шкафа — {name}" + }, + "public_bookcase-start_date": { "question": "Когда был установлен этот общественный книжный шкаф?", "render": "Установлен {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?", "render": "Более подробная информация на сайте" } @@ -868,7 +864,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -905,7 +901,43 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Свободный доступ" + }, + "1": { + "then": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" + }, + "2": { + "then": "Доступ только членам клуба" + } + }, + "question": "Есть ли свободный доступ к этой спортивной площадке?" + }, + "sport-pitch-reservation": { + "mappings": { + "1": { + "then": "Желательна предварительная запись для доступа на эту спортивную площадку" + }, + "2": { + "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" + }, + "3": { + "then": "Невозможна предварительная запись" + } + }, + "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Всегда доступен" + } + }, + "question": "В какое время доступна эта площадка?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Здесь можно играть в баскетбол" @@ -927,7 +959,7 @@ } } }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -947,42 +979,6 @@ }, "question": "Какое покрытие на этой спортивной площадке?", "render": "Поверхность - {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Свободный доступ" - }, - "1": { - "then": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" - }, - "2": { - "then": "Доступ только членам клуба" - } - }, - "question": "Есть ли свободный доступ к этой спортивной площадке?" - }, - "4": { - "mappings": { - "1": { - "then": "Желательна предварительная запись для доступа на эту спортивную площадку" - }, - "2": { - "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" - }, - "3": { - "then": "Невозможна предварительная запись" - } - }, - "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" - }, - "7": { - "mappings": { - "1": { - "then": "Всегда доступен" - } - }, - "question": "В какое время доступна эта площадка?" } }, "title": { @@ -992,7 +988,7 @@ "surveillance_camera": { "name": "Камеры наблюдения", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "1": { "then": "Камера с поворотным механизмом" @@ -1003,7 +999,7 @@ }, "question": "Какая это камера?" }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "1": { "then": "Эта камера расположена снаружи" @@ -1013,7 +1009,7 @@ } } }, - "8": { + "camera:mount": { "question": "Как расположена эта камера?" } }, @@ -1026,14 +1022,14 @@ "presets": { "0": { "description": "Туалет или комната отдыха со свободным доступом", - "title": "Туалет" + "title": "tуалет" }, "1": { - "title": "Туалет с доступом для пользователей кресел-колясок" + "title": "tуалет с доступом для пользователей кресел-колясок" } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Свободный доступ" @@ -1047,26 +1043,26 @@ }, "question": "Есть ли свободный доступ к этим туалетам?" }, - "2": { + "toilet-charge": { + "question": "Сколько стоит посещение туалета?", + "render": "Стоимость {charge}" + }, + "toilets-fee": { "mappings": { "0": { "then": "Это платные туалеты" } } }, - "3": { - "question": "Сколько стоит посещение туалета?", - "render": "Стоимость {charge}" + "toilets-type": { + "question": "Какие это туалеты?" }, - "4": { + "toilets-wheelchair": { "mappings": { "1": { "then": "Недоступно пользователям кресел-колясок" } } - }, - "5": { - "question": "Какие это туалеты?" } }, "title": { @@ -1089,15 +1085,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Высота: {height} м" - } - }, - "render": "Высота: {height}" - }, - "4": { + "tree-decidouous": { "mappings": { "0": { "then": "Листопадное: у дерева опадают листья в определённое время года." @@ -1108,7 +1096,15 @@ }, "question": "Это дерево вечнозелёное или листопадное?" }, - "5": { + "tree-height": { + "mappings": { + "0": { + "then": "Высота: {height} м" + } + }, + "render": "Высота: {height}" + }, + "tree_node-name": { "mappings": { "0": { "then": "У этого дерева нет названия." @@ -1117,10 +1113,10 @@ "question": "Есть ли у этого дерева название?", "render": "Название: {name}" }, - "7": { + "tree_node-ref:OnroerendErfgoed": { "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "render": "\"\"/ Wikidata: {wikidata}" } }, @@ -1141,7 +1137,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Вы хотите добавить описание?" } }, diff --git a/langs/layers/zh_Hans.json b/langs/layers/zh_Hans.json index de1601cf5..360a52c61 100644 --- a/langs/layers/zh_Hans.json +++ b/langs/layers/zh_Hans.json @@ -3,12 +3,11 @@ "name": "长椅", "presets": { "0": { - "description": "增加一个新的长椅", "title": "长椅" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "靠背:有" @@ -20,38 +19,7 @@ "question": "这个长椅有靠背吗?", "render": "靠背" }, - "2": { - "question": "这个长椅有几个座位?" - }, - "3": { - "mappings": { - "0": { - "then": "材质:木" - }, - "1": { - "then": "材质:金属" - }, - "2": { - "then": "材质:石头" - }, - "3": { - "then": "材质:混凝土" - }, - "4": { - "then": "材质:塑料" - }, - "5": { - "then": "材质:不锈钢" - } - }, - "question": "这个长椅(或座椅)是用什么材料做的?", - "render": "材质: {material}" - }, - "4": { - "question": "坐在长椅上的时候你目视的方向是哪边?", - "render": "坐在长椅上的时候目视方向为 {direction}°方位。" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "颜色:棕" @@ -81,7 +49,38 @@ "question": "这个长椅是什么颜色的?", "render": "颜色: {colour}" }, - "6": { + "bench-direction": { + "question": "坐在长椅上的时候你目视的方向是哪边?", + "render": "坐在长椅上的时候目视方向为 {direction}°方位。" + }, + "bench-material": { + "mappings": { + "0": { + "then": "材质:木" + }, + "1": { + "then": "材质:金属" + }, + "2": { + "then": "材质:石头" + }, + "3": { + "then": "材质:混凝土" + }, + "4": { + "then": "材质:塑料" + }, + "5": { + "then": "材质:不锈钢" + } + }, + "question": "这个长椅(或座椅)是用什么材料做的?", + "render": "材质: {material}" + }, + "bench-seats": { + "question": "这个长椅有几个座位?" + }, + "bench-survey:date": { "question": "上次对这个长椅实地调查是什么时候?", "render": "这个长椅于 {survey:date}最后一次实地调查" } @@ -93,11 +92,11 @@ "bench_at_pt": { "name": "在公交站点的长椅", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "站立长凳" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -114,14 +113,14 @@ }, "bicycle_library": { "tagRenderings": { - "7": { + "bicycle-library-target-group": { "question": "谁可以从这里借自行车?" } } }, "bicycle_tube_vending_machine": { "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "这个借还机正常工作" @@ -144,11 +143,7 @@ } }, "tagRenderings": { - "1": { - "question": "这个自行车咖啡的名字是什么?", - "render": "这家自行车咖啡叫做 {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "这家自行车咖啡为每个人提供打气筒" @@ -159,18 +154,20 @@ }, "question": "这家自行车咖啡为每个使用者提供打气筒吗?" }, - "3": { - "mappings": { - "0": { - "then": "这家自行车咖啡为DIY修理者提供工具" - }, - "1": { - "then": "这家自行车咖啡不为DIY修理者提供工具" - } - }, - "question": "这里有供你修车用的工具吗?" + "bike_cafe-email": { + "question": "{name}的电子邮箱是什么?" }, - "4": { + "bike_cafe-name": { + "question": "这个自行车咖啡的名字是什么?", + "render": "这家自行车咖啡叫做 {name}" + }, + "bike_cafe-opening_hours": { + "question": "这家自行车咖啡什么时候开门营业?" + }, + "bike_cafe-phone": { + "question": "{name}的电话号码是什么?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "这家自行车咖啡可以修车" @@ -181,17 +178,19 @@ }, "question": "这家自行车咖啡t提供修车服务吗?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "这家自行车咖啡为DIY修理者提供工具" + }, + "1": { + "then": "这家自行车咖啡不为DIY修理者提供工具" + } + }, + "question": "这里有供你修车用的工具吗?" + }, + "bike_cafe-website": { "question": "{name}的网站是什么?" - }, - "6": { - "question": "{name}的电话号码是什么?" - }, - "7": { - "question": "{name}的电子邮箱是什么?" - }, - "8": { - "question": "这家自行车咖啡什么时候开门营业?" } }, "title": { diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 00df6ac59..ccacafa7f 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -3,12 +3,11 @@ "name": "長椅", "presets": { "0": { - "description": "新增長椅", "title": "長椅" } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "靠背:有" @@ -20,39 +19,7 @@ "question": "這個長椅是否有靠背?", "render": "靠背" }, - "2": { - "question": "這個長椅有幾個位子?", - "render": "{seats} 座位數" - }, - "3": { - "mappings": { - "0": { - "then": "材質:木頭" - }, - "1": { - "then": "材質:金屬" - }, - "2": { - "then": "材質:石頭" - }, - "3": { - "then": "材質:水泥" - }, - "4": { - "then": "材質:塑膠" - }, - "5": { - "then": "材質:鋼鐵" - } - }, - "question": "這個長椅 (座位) 是什麼做的?", - "render": "材質:{material}" - }, - "4": { - "question": "坐在長椅時是面對那個方向?", - "render": "當坐在長椅時,那個人朝向 {direction}°。" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "顏色:棕色" @@ -82,7 +49,39 @@ "question": "這個長椅是什麼顏色的?", "render": "顏色:{colour}" }, - "6": { + "bench-direction": { + "question": "坐在長椅時是面對那個方向?", + "render": "當坐在長椅時,那個人朝向 {direction}°。" + }, + "bench-material": { + "mappings": { + "0": { + "then": "材質:木頭" + }, + "1": { + "then": "材質:金屬" + }, + "2": { + "then": "材質:石頭" + }, + "3": { + "then": "材質:水泥" + }, + "4": { + "then": "材質:塑膠" + }, + "5": { + "then": "材質:鋼鐵" + } + }, + "question": "這個長椅 (座位) 是什麼做的?", + "render": "材質:{material}" + }, + "bench-seats": { + "question": "這個長椅有幾個位子?", + "render": "{seats} 座位數" + }, + "bench-survey:date": { "question": "上一次探察長椅是什麼時候?", "render": "這個長椅最後是在 {survey:date} 探查的" } @@ -94,11 +93,11 @@ "bench_at_pt": { "name": "大眾運輸站點的長椅", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "站立長椅" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +122,7 @@ } }, "tagRenderings": { - "1": { - "question": "這個單車圖書館的名稱是?", - "render": "這個單車圖書館叫做 {name}" - }, - "6": { - "mappings": { - "0": { - "then": "租借單車免費" - }, - "1": { - "then": "租借單車價錢 €20/year 與 €20 保證金" - } - }, - "question": "租用單車的費用多少?", - "render": "租借單車需要 {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "提供兒童單車" @@ -152,6 +135,22 @@ } }, "question": "誰可以在這裡租單車?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "租借單車免費" + }, + "1": { + "then": "租借單車價錢 €20/year 與 €20 保證金" + } + }, + "question": "租用單車的費用多少?", + "render": "租借單車需要 {charge}" + }, + "bicycle_library-name": { + "question": "這個單車圖書館的名稱是?", + "render": "這個單車圖書館叫做 {name}" } }, "title": { @@ -166,7 +165,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "這個自動販賣機仍運作" @@ -194,11 +193,7 @@ } }, "tagRenderings": { - "1": { - "question": "這個單車咖啡廳的名稱是?", - "render": "這個單車咖啡廳叫做 {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬" @@ -209,18 +204,20 @@ }, "question": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" }, - "3": { - "mappings": { - "0": { - "then": "這個單車咖啡廳提供工具讓你修理" - }, - "1": { - "then": "這個單車咖啡廳並沒有提供工具讓你修理" - } - }, - "question": "這裡是否有工具修理你的單車嗎?" + "bike_cafe-email": { + "question": "{name} 的電子郵件地址是?" }, - "4": { + "bike_cafe-name": { + "question": "這個單車咖啡廳的名稱是?", + "render": "這個單車咖啡廳叫做 {name}" + }, + "bike_cafe-opening_hours": { + "question": "何時這個單車咖啡廳營運?" + }, + "bike_cafe-phone": { + "question": "{name} 的電話號碼是?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "這個單車咖啡廳修理單車" @@ -231,17 +228,19 @@ }, "question": "這個單車咖啡廳是否能修理單車?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "這個單車咖啡廳提供工具讓你修理" + }, + "1": { + "then": "這個單車咖啡廳並沒有提供工具讓你修理" + } + }, + "question": "這裡是否有工具修理你的單車嗎?" + }, + "bike_cafe-website": { "question": "{name} 的網站是?" - }, - "6": { - "question": "{name} 的電話號碼是?" - }, - "7": { - "question": "{name} 的電子郵件地址是?" - }, - "8": { - "question": "何時這個單車咖啡廳營運?" } }, "title": { @@ -269,20 +268,6 @@ "render": "單車清理服務" } }, - "bike_monitoring_station": { - "name": "監視站", - "title": { - "mappings": { - "0": { - "then": "單車計數站 {name}" - }, - "1": { - "then": "單車計數站 {ref}" - } - }, - "render": "單車計數站" - } - }, "bike_parking": { "name": "單車停車場", "presets": { @@ -291,7 +276,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "公開可用" + }, + "1": { + "then": "通行性主要是為了企業的顧客" + }, + "2": { + "then": "通行性僅限學校、公司或組織的成員" + } + }, + "question": "誰可以使用這個單車停車場?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "單車架 " @@ -321,7 +321,33 @@ "question": "這是那種類型的單車停車場?", "render": "這個單車停車場的類型是:{bicycle_parking}" }, - "2": { + "Capacity": { + "question": "這個單車停車場能放幾台單車 (包括裝箱單車)?", + "render": "{capacity} 單車的地方" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "這個停車場有地方可以放裝箱單車" + }, + "1": { + "then": "這停車場有設計 (官方) 空間給裝箱的單車。" + } + }, + "question": "這個單車停車場有地方放裝箱的單車嗎?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "這個停車場有遮蔽 (有屋頂)" + }, + "1": { + "then": "這個停車場沒有遮蔽" + } + }, + "question": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。" + }, + "Underground?": { "mappings": { "0": { "then": "地下停車場" @@ -340,47 +366,6 @@ } }, "question": "這個單車停車場的相對位置是?" - }, - "3": { - "mappings": { - "0": { - "then": "這個停車場有遮蔽 (有屋頂)" - }, - "1": { - "then": "這個停車場沒有遮蔽" - } - }, - "question": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。" - }, - "4": { - "question": "這個單車停車場能放幾台單車 (包括裝箱單車)?", - "render": "{capacity} 單車的地方" - }, - "5": { - "mappings": { - "0": { - "then": "公開可用" - }, - "1": { - "then": "通行性主要是為了企業的顧客" - }, - "2": { - "then": "通行性僅限學校、公司或組織的成員" - } - }, - "question": "誰可以使用這個單車停車場?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "這個停車場有地方可以放裝箱單車" - }, - "1": { - "then": "這停車場有設計 (官方) 空間給裝箱的單車。" - } - }, - "question": "這個單車停車場有地方放裝箱的單車嗎?" } }, "title": { @@ -391,12 +376,12 @@ "description": "充電站", "name": "充電站", "tagRenderings": { - "41": { - "question": "何時是充電站開放使用的時間?" - }, - "42": { + "Auth phone": { "question": "充電站所屬的網路是?", "render": "{network}" + }, + "Authentication": { + "question": "何時是充電站開放使用的時間?" } }, "title": { diff --git a/langs/layers/zh_Hanå¨s.json b/langs/layers/zh_Hanå¨s.json index 8a25d1e17..0efb21822 100644 --- a/langs/layers/zh_Hanå¨s.json +++ b/langs/layers/zh_Hanå¨s.json @@ -1,7 +1,7 @@ { "bench": { "tagRenderings": { - "3": { + "bench-material": { "render": "材质: {material}" } } diff --git a/langs/pt.json b/langs/pt.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/langs/pt.json @@ -0,0 +1 @@ +{} diff --git a/langs/shared-questions/pt.json b/langs/shared-questions/pt.json new file mode 100644 index 000000000..4ba738f83 --- /dev/null +++ b/langs/shared-questions/pt.json @@ -0,0 +1,27 @@ +{ + "undefined": { + "description": { + "question": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" + }, + "email": { + "question": "Qual é o endereço de e-mail de {name}?" + }, + "level": { + "mappings": { + "0": { + "then": "Está no subsolo" + }, + "1": { + "then": "Está ao nível do rés-do-chão" + }, + "2": { + "then": "Está ao nível do rés-do-chão" + }, + "3": { + "then": "Está no primeiro andar" + } + }, + "question": "Em que nível se encontra este elemento?" + } + } +} \ No newline at end of file diff --git a/langs/themes/ca.json b/langs/themes/ca.json index 6832bb590..79eb7a4c2 100644 --- a/langs/themes/ca.json +++ b/langs/themes/ca.json @@ -7,35 +7,35 @@ "layers": { "0": { "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } } }, "1": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, "2": { "tagRenderings": { - "3": { + "Name": { "render": "{name}" } } }, "3": { "tagRenderings": { - "6": { + "name": { "render": "{name}" } } }, "4": { "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -50,10 +50,10 @@ "layers": { "0": { "tagRenderings": { - "3": { + "shops-phone": { "render": "{phone}" }, - "4": { + "shops-website": { "render": "{website}" } } diff --git a/langs/themes/de.json b/langs/themes/de.json index 934363b63..300eacddc 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Welcher Künstler hat das geschaffen?", + "render": "Erstellt von {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architektur" @@ -57,15 +61,11 @@ "question": "Was ist die Art dieses Kunstwerks?", "render": "Dies ist ein {artwork_type}" }, - "2": { - "question": "Welcher Künstler hat das geschaffen?", - "render": "Erstellt von {artist_name}" - }, - "3": { + "artwork-website": { "question": "Gibt es eine Website mit weiteren Informationen über dieses Kunstwerk?", "render": "Weitere Informationen auf dieser Webseite" }, - "4": { + "artwork-wikidata": { "question": "Welcher Wikidata-Eintrag entspricht diesem Kunstwerk?", "render": "Entspricht {wikidata}" } @@ -112,7 +112,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "question": "Wie lautet der Name dieses Vereins oder Organisation?", "render": "{name}" } @@ -130,7 +130,7 @@ "description": "Eine Kletterhalle", "name": "Kletterhallen", "tagRenderings": { - "3": { + "name": { "question": "Wie heißt diese Kletterhalle?", "render": "{name}" } @@ -147,7 +147,13 @@ "2": { "name": "Kletterrouten", "tagRenderings": { - "3": { + "Difficulty": { + "render": "Die Schwierigkeit ist {climbing:grade:french} entsprechend des französisch/belgischen Systems" + }, + "Length": { + "render": "Diese Route ist {canonical(climbing:length)} lang" + }, + "Name": { "mappings": { "0": { "then": "Diese Kletterroute hat keinen Namen" @@ -155,12 +161,6 @@ }, "question": "Wie heißt diese Kletterroute?", "render": "{name}" - }, - "4": { - "render": "Diese Route ist {canonical(climbing:length)} lang" - }, - "5": { - "render": "Die Schwierigkeit ist {climbing:grade:french} entsprechend des französisch/belgischen Systems" } }, "title": { @@ -182,7 +182,7 @@ } }, "tagRenderings": { - "6": { + "name": { "mappings": { "0": { "then": "Diese Klettergelegenheit hat keinen Namen" @@ -200,10 +200,10 @@ "description": "Eine Klettergelegenheit?", "name": "Klettermöglichkeiten?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Hier kann nicht geklettert werden" diff --git a/langs/themes/en.json b/langs/themes/en.json index e96960d80..b62768bef 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Which artist created this?", + "render": "Created by {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architecture" @@ -57,15 +61,11 @@ "question": "What is the type of this artwork?", "render": "This is a {artwork_type}" }, - "2": { - "question": "Which artist created this?", - "render": "Created by {artist_name}" - }, - "3": { + "artwork-website": { "question": "Is there a website with more information about this artwork?", "render": "More information on this website" }, - "4": { + "artwork-wikidata": { "question": "Which Wikidata-entry corresponds with this artwork?", "render": "Corresponds with {wikidata}" } @@ -91,11 +91,6 @@ "description": "A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike", "title": "Bicycle libraries" }, - "bike_monitoring_stations": { - "description": "This theme shows bike monitoring stations with live data", - "shortDescription": "Bike monitoring stations with live data from Brussels Mobility", - "title": "Bike Monitoring stations" - }, "binoculars": { "description": "A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve.", "shortDescription": "A map with fixed binoculars", @@ -121,11 +116,19 @@ } }, "tagRenderings": { - "1": { - "question": "What is this place called?", - "render": "This place is called {name}" + "caravansites-capacity": { + "question": "How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)", + "render": "{capacity} campers can use this place at the same time" }, - "2": { + "caravansites-charge": { + "question": "How much does this place charge?", + "render": "This place charges {charge}" + }, + "caravansites-description": { + "question": "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)", + "render": "More details about this place: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "You need to pay for use" @@ -136,26 +139,7 @@ }, "question": "Does this place charge a fee?" }, - "3": { - "question": "How much does this place charge?", - "render": "This place charges {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "This place has a sanitary dump station" - }, - "1": { - "then": "This place does not have a sanitary dump station" - } - }, - "question": "Does this place have a sanitary dump station?" - }, - "5": { - "question": "How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)", - "render": "{capacity} campers can use this place at the same time" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "There is internet access" @@ -169,7 +153,7 @@ }, "question": "Does this place provide internet access?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "You need to pay extra for internet access" @@ -180,22 +164,7 @@ }, "question": "Do you have to pay for the internet access?" }, - "8": { - "mappings": { - "0": { - "then": "This place has toilets" - }, - "1": { - "then": "This place does not have toilets" - } - }, - "question": "Does this place have toilets?" - }, - "9": { - "question": "Does this place have a website?", - "render": "Official website: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Yes, there are some spots for long term rental, but you can also stay on a daily basis" @@ -209,9 +178,35 @@ }, "question": "Does this place offer spots for long term rental?" }, - "11": { - "question": "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)", - "render": "More details about this place: {description}" + "caravansites-name": { + "question": "What is this place called?", + "render": "This place is called {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "This place has a sanitary dump station" + }, + "1": { + "then": "This place does not have a sanitary dump station" + } + }, + "question": "Does this place have a sanitary dump station?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "This place has toilets" + }, + "1": { + "then": "This place does not have toilets" + } + }, + "question": "Does this place have toilets?" + }, + "caravansites-website": { + "question": "Does this place have a website?", + "render": "Official website: {website}" } }, "title": { @@ -233,55 +228,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "You need to pay for use" - }, - "1": { - "then": "Can be used for free" - } - }, - "question": "Does this place charge a fee?" - }, - "2": { - "question": "How much does this place charge?", - "render": "This place charges {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "This place has a water point" - }, - "1": { - "then": "This place does not have a water point" - } - }, - "question": "Does this place have a water point?" - }, - "4": { - "mappings": { - "0": { - "then": "You can dispose of grey water here" - }, - "1": { - "then": "You cannot dispose of gray water here" - } - }, - "question": "Can you dispose of grey water here?" - }, - "5": { - "mappings": { - "0": { - "then": "You can dispose of chemical toilet waste here" - }, - "1": { - "then": "You cannot dispose of chemical toilet waste here" - } - }, - "question": "Can you dispose of chemical toilet waste here?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "You need a network key/code to use this" @@ -298,9 +245,57 @@ }, "question": "Who can use this dump station?" }, - "7": { + "dumpstations-charge": { + "question": "How much does this place charge?", + "render": "This place charges {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "You can dispose of chemical toilet waste here" + }, + "1": { + "then": "You cannot dispose of chemical toilet waste here" + } + }, + "question": "Can you dispose of chemical toilet waste here?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "You need to pay for use" + }, + "1": { + "then": "Can be used for free" + } + }, + "question": "Does this place charge a fee?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "You can dispose of grey water here" + }, + "1": { + "then": "You cannot dispose of gray water here" + } + }, + "question": "Can you dispose of grey water here?" + }, + "dumpstations-network": { "question": "What network is this place a part of? (skip if none)", "render": "This station is part of network {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "This place has a water point" + }, + "1": { + "then": "This place does not have a water point" + } + }, + "question": "Does this place have a water point?" } }, "title": { @@ -356,7 +351,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "question": "What is the name of this climbing club or NGO?", "render": "{name}" } @@ -374,7 +369,7 @@ "description": "A climbing gym", "name": "Climbing gyms", "tagRenderings": { - "3": { + "name": { "question": "What is the name of this climbing gym?", "render": "{name}" } @@ -396,24 +391,7 @@ } }, "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "This climbing route doesn't have a name" - } - }, - "question": "What is the name of this climbing route?", - "render": "{name}" - }, - "4": { - "question": "How long is this climbing route (in meters)?", - "render": "This route is {canonical(climbing:length)} long" - }, - "5": { - "question": "What is the difficulty of this climbing route according to the french/belgian system?", - "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" - }, - "6": { + "Bolts": { "mappings": { "0": { "then": "This route is not bolted" @@ -425,7 +403,24 @@ "question": "How much bolts does this route have before reaching the moulinette?", "render": "This route has {climbing:bolts} bolts" }, - "8": { + "Difficulty": { + "question": "What is the difficulty of this climbing route according to the french/belgian system?", + "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" + }, + "Length": { + "question": "How long is this climbing route (in meters)?", + "render": "This route is {canonical(climbing:length)} long" + }, + "Name": { + "mappings": { + "0": { + "then": "This climbing route doesn't have a name" + } + }, + "question": "What is the name of this climbing route?", + "render": "{name}" + }, + "Rock type": { "render": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag" } }, @@ -448,25 +443,25 @@ } }, "tagRenderings": { - "3": { - "render": "

Length overview

{histogram(_length_hist)}" - }, - "4": { - "render": "

Difficulties overview

{histogram(_difficulty_hist)}" - }, - "5": { + "Containe {_contained_climbing_routes_count} routes": { "render": "

Contains {_contained_climbing_routes_count} routes

    {_contained_climbing_routes}
" }, - "6": { + "Contained routes hist": { + "render": "

Difficulties overview

{histogram(_difficulty_hist)}" + }, + "Contained routes length hist": { + "render": "

Length overview

{histogram(_length_hist)}" + }, + "Rock type (crag/rock/cliff only)": { "mappings": { "0": { - "then": "This climbing opportunity doesn't have a name" + "then": "Limestone" } }, - "question": "What is the name of this climbing opportunity?", - "render": "{name}" + "question": "What is the rock type here?", + "render": "The rock type is {rock}" }, - "7": { + "Type": { "mappings": { "0": { "then": "A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without rope" @@ -476,14 +471,14 @@ } } }, - "8": { + "name": { "mappings": { "0": { - "then": "Limestone" + "then": "This climbing opportunity doesn't have a name" } }, - "question": "What is the rock type here?", - "render": "The rock type is {rock}" + "question": "What is the name of this climbing opportunity?", + "render": "{name}" } }, "title": { @@ -508,10 +503,10 @@ "description": "A climbing opportunity?", "name": "Climbing opportunities?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Climbing is not possible here" @@ -761,40 +756,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Extra describing info about the garden (if needed and not yet described above)", + "render": "More details: {description}" + }, + "facadegardens-direction": { "question": "What is the orientation of the garden?", "render": "Orientation: {direction} (where 0=N and 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "The garden is in full sun" - }, - "1": { - "then": "The garden is in partial shade" - }, - "2": { - "then": "The garden is in the shade" - } - }, - "question": "Is the garden shaded or sunny?" - }, - "3": { - "mappings": { - "0": { - "then": "There is a rain barrel" - }, - "1": { - "then": "There is no rain barrel" - } - }, - "question": "Is there a water barrel installed for the garden?" - }, - "4": { - "question": "When was the garden constructed? (a year is sufficient)", - "render": "Construction date of the garden: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "There are edible plants" @@ -805,7 +775,7 @@ }, "question": "Are there any edible plants?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "There are vines" @@ -822,9 +792,34 @@ }, "question": "What kinds of plants grow here?" }, - "7": { - "question": "Extra describing info about the garden (if needed and not yet described above)", - "render": "More details: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "There is a rain barrel" + }, + "1": { + "then": "There is no rain barrel" + } + }, + "question": "Is there a water barrel installed for the garden?" + }, + "facadegardens-start_date": { + "question": "When was the garden constructed? (a year is sufficient)", + "render": "Construction date of the garden: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "The garden is in full sun" + }, + "1": { + "then": "The garden is in partial shade" + }, + "2": { + "then": "The garden is in the shade" + } + }, + "question": "Is the garden shaded or sunny?" } }, "title": { @@ -875,7 +870,35 @@ } }, "tagRenderings": { - "0": { + "hackerspaces-name": { + "question": "What is the name of this hackerspace?", + "render": "This hackerspace is named {name}" + }, + "hackerspaces-opening_hours": { + "mappings": { + "0": { + "then": "Opened 24/7" + } + }, + "question": "When is this hackerspace opened?", + "render": "{opening_hours_table()}" + }, + "hackerspaces-start_date": { + "question": "When was this hackerspace founded?", + "render": "This hackerspace was founded at {start_date}" + }, + "hs-club-mate": { + "mappings": { + "0": { + "then": "This hackerspace serves club mate" + }, + "1": { + "then": "This hackerspace does not serve club mate" + } + }, + "question": "Does this hackerspace serve Club Mate?" + }, + "is_makerspace": { "mappings": { "0": { "then": "This is a makerspace" @@ -885,34 +908,6 @@ } }, "question": "Is this a hackerspace or a makerspace?" - }, - "1": { - "question": "What is the name of this hackerspace?", - "render": "This hackerspace is named {name}" - }, - "5": { - "mappings": { - "0": { - "then": "Opened 24/7" - } - }, - "question": "When is this hackerspace opened?", - "render": "{opening_hours_table()}" - }, - "7": { - "mappings": { - "0": { - "then": "This hackerspace serves club mate" - }, - "1": { - "then": "This hackerspace is not worthy of the name hackerspace as it does not serve club mate" - } - }, - "question": "Does this hackerspace serve Club Mate?" - }, - "8": { - "question": "When was this hackerspace founded?", - "render": "This hackerspace was founded at {start_date}" } }, "title": { @@ -941,7 +936,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "The hydrant color is unknown." @@ -956,7 +951,22 @@ "question": "What color is the hydrant?", "render": "The hydrant color is {colour}" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "The hydrant is (fully or partially) working." + }, + "1": { + "then": "The hydrant is unavailable." + }, + "2": { + "then": "The hydrant has been removed." + } + }, + "question": "Update the lifecycle status of the hydrant.", + "render": "Lifecycle status" + }, + "hydrant-type": { "mappings": { "0": { "then": "The hydrant type is unknown." @@ -976,21 +986,6 @@ }, "question": "What type of hydrant is it?", "render": " Hydrant type: {fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "The hydrant is (fully or partially) working." - }, - "1": { - "then": "The hydrant is unavailable." - }, - "2": { - "then": "The hydrant has been removed." - } - }, - "question": "Update the lifecycle status of the hydrant.", - "render": "Lifecycle status" } }, "title": { @@ -1007,7 +1002,7 @@ } }, "tagRenderings": { - "0": { + "extinguisher-location": { "mappings": { "0": { "then": "Found indoors." @@ -1034,19 +1029,7 @@ } }, "tagRenderings": { - "0": { - "question": "What is the name of this fire station?", - "render": "This station is called {name}." - }, - "1": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - }, - "2": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "3": { + "station-agency": { "mappings": { "0": { "then": "Bureau of Fire Protection" @@ -1055,7 +1038,11 @@ "question": "What agency operates this station?", "render": "This station is operated by {operator}." }, - "4": { + "station-name": { + "question": "What is the name of this fire station?", + "render": "This station is called {name}." + }, + "station-operator": { "mappings": { "0": { "then": "The station is operated by the government." @@ -1072,6 +1059,14 @@ }, "question": "How is the station operator classified?", "render": "The operator is a(n) {operator:type} entity." + }, + "station-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "station-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." } }, "title": { @@ -1088,23 +1083,15 @@ } }, "tagRenderings": { - "0": { - "question": "What is the name of this ambulance station?", - "render": "This station is called {name}." - }, - "1": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - }, - "2": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "3": { + "ambulance-agency": { "question": "What agency operates this station?", "render": "This station is operated by {operator}." }, - "4": { + "ambulance-name": { + "question": "What is the name of this ambulance station?", + "render": "This station is called {name}." + }, + "ambulance-operator-type": { "mappings": { "0": { "then": "The station is operated by the government." @@ -1121,6 +1108,14 @@ }, "question": "How is the station operator classified?", "render": "The operator is a(n) {operator:type} entity." + }, + "ambulance-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "ambulance-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." } }, "title": { @@ -1157,23 +1152,23 @@ } }, "tagRenderings": { - "0": { - "question": "What is the power output of this wind turbine? (e.g. 2.3 MW)", - "render": "The power output of this wind turbine is {generator:output:electricity}." - }, - "1": { - "question": "Who operates this wind turbine?", - "render": "This wind turbine is operated by {operator}." - }, - "2": { - "question": "What is the total height of this wind turbine (including rotor radius), in metres?", - "render": "The total height (including rotor radius) of this wind turbine is {height} metres." - }, - "3": { + "turbine-diameter": { "question": "What is the rotor diameter of this wind turbine, in metres?", "render": "The rotor diameter of this wind turbine is {rotor:diameter} metres." }, - "4": { + "turbine-height": { + "question": "What is the total height of this wind turbine (including rotor radius), in metres?", + "render": "The total height (including rotor radius) of this wind turbine is {height} metres." + }, + "turbine-operator": { + "question": "Who operates this wind turbine?", + "render": "This wind turbine is operated by {operator}." + }, + "turbine-output": { + "question": "What is the power output of this wind turbine? (e.g. 2.3 MW)", + "render": "The power output of this wind turbine is {generator:output:electricity}." + }, + "turbine-start-date": { "question": "When did this wind turbine go into operation?", "render": "This wind turbine went into operation on/in {start_date}." } @@ -1221,7 +1216,7 @@ "title": "Parking" }, "personal": { - "description": "Create a personal theme based on all the available layers of all themes", + "description": "Create a personal theme based on all the available layers of all themes. In order to show some data, open layer selection", "title": "Personal theme" }, "playgrounds": { @@ -1242,10 +1237,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "What is the email address of this shop?", + "render": "{email}" + }, + "shops-name": { "question": "What is the name of this shop?" }, - "2": { + "shops-opening_hours": { + "question": "What are the opening hours of this shop?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "What is the phone number?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "Convenience store" @@ -1272,21 +1279,9 @@ "question": "What does this shop sell?", "render": "This shop sells {shop}" }, - "3": { - "question": "What is the phone number?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "What is the website of this shop?", "render": "{website}" - }, - "5": { - "question": "What is the email address of this shop?", - "render": "{email}" - }, - "6": { - "question": "What are the opening hours of this shop?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { @@ -1331,10 +1326,10 @@ "description": "Addresses", "name": "Known addresses in OSM", "tagRenderings": { - "0": { + "uk_addresses_explanation_osm": { "render": "This address is saved in OpenStreetMap" }, - "1": { + "uk_addresses_housenumber": { "mappings": { "0": { "then": "This building has no house number" @@ -1343,7 +1338,7 @@ "question": "What is the number of this house?", "render": "The housenumber is {addr:housenumber}" }, - "2": { + "uk_addresses_street": { "question": "What street is this address located in?", "render": "This address is in street {addr:street}" } diff --git a/langs/themes/es.json b/langs/themes/es.json index 158b8b000..80196c809 100644 --- a/langs/themes/es.json +++ b/langs/themes/es.json @@ -15,7 +15,7 @@ } }, "tagRenderings": { - "1": { + "artwork-artwork_type": { "question": "Cuál es el tipo de esta obra de arte?", "render": "Esta es un {artwork_type}" } diff --git a/langs/themes/fr.json b/langs/themes/fr.json index 8bf6696c9..530b9acb0 100644 --- a/langs/themes/fr.json +++ b/langs/themes/fr.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Quel artiste a créé cette œuvre ?", + "render": "Créé par {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architecture" @@ -57,15 +61,11 @@ "question": "Quel est le type de cette œuvre d'art?", "render": "Type d'œuvre : {artwork_type}" }, - "2": { - "question": "Quel artiste a créé cette œuvre ?", - "render": "Créé par {artist_name}" - }, - "3": { + "artwork-website": { "question": "Existe-t-il un site web où trouver plus d'informations sur cette œuvre d'art ?", "render": "Plus d'info sûr ce site web" }, - "4": { + "artwork-wikidata": { "question": "Quelle entrée Wikidata correspond à cette œuvre d'art ?", "render": "Correspond à {wikidata}" } @@ -91,11 +91,6 @@ "description": "Une vélothèque est un endroit où on peut emprunter des vélos, souvent moyennant une petite somme annuelle. Un cas d'utilisation notable est celui des vélothèques pour les enfants, qui leur permettent de passer à un vélo plus grand quand ils sont trop grands pour leur vélo actuel", "title": "Vélothèques" }, - "bike_monitoring_stations": { - "description": "Ce thème montre les données des compteurs en temps réel", - "shortDescription": "Station de comptage vélo avec données en temps réel par Bruxelles Mobilités", - "title": "Station de comptage vélo" - }, "bookcases": { "description": "Une microbibliothèques, également appelée boite à livre, est un élément de mobilier urbain (étagère, armoire, etc) dans lequel sont stockés des livres et autres objets en accès libre. Découvrez les boites à livres prêt de chez vous, ou ajouter en une nouvelle à l'aide de votre compte OpenStreetMap.", "title": "Carte des microbibliothèques" @@ -113,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Comment s'appelle cet endroit ?", - "render": "Cet endroit s'appelle {nom}" + "caravansites-capacity": { + "question": "Combien de personnes peuvent camper ici ? (Passez s’il n’y a pas de places délimitées)", + "render": "{capacity} personnes peuvent utiliser cet espace en même temps" }, - "2": { + "caravansites-charge": { + "question": "Combien coûte cet endroit ?", + "render": "Ce site fait payer {charge}" + }, + "caravansites-description": { + "question": "Souhaitez-vous ajouter une description générale du lieu ? (Ne pas répéter les informations précédentes et rester neutre, les opinions vont dans les avis)", + "render": "Plus de détails à propos du site : {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "L’utilisation est payante" @@ -128,26 +131,7 @@ }, "question": "Cet endroit est-il payant ?" }, - "3": { - "question": "Combien coûte cet endroit ?", - "render": "Ce site fait payer {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Cet endroit a une station de vidange sanitaire" - }, - "1": { - "then": "Ce site ne possède pas de lieu de vidange" - } - }, - "question": "Ce site possède-t’il un lieu de vidange ?" - }, - "5": { - "question": "Combien de personnes peuvent camper ici ? (Passez s’il n’y a pas de places délimitées)", - "render": "{capacity} personnes peuvent utiliser cet espace en même temps" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Il y a un accès internet" @@ -161,7 +145,7 @@ }, "question": "Cet endroit offre-t-il un accès à Internet ?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "L’accès internet est en supplément" @@ -172,22 +156,7 @@ }, "question": "L’accès internet est-il payant ?" }, - "8": { - "mappings": { - "0": { - "then": "Ce site a des toilettes" - }, - "1": { - "then": "Ce site n’a pas de toilettes" - } - }, - "question": "Y-a-t’il des toilettes sur le site ?" - }, - "9": { - "question": "Ce lieu a-t’il un site internet ?", - "render": "Site officiel : {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Oui, mais il est possible d’y passer seulement une nuit" @@ -201,9 +170,35 @@ }, "question": "Ce site permet-il la location longue durée ?" }, - "11": { - "question": "Souhaitez-vous ajouter une description générale du lieu ? (Ne pas répéter les informations précédentes et rester neutre, les opinions vont dans les avis)", - "render": "Plus de détails à propos du site : {description}" + "caravansites-name": { + "question": "Comment s'appelle cet endroit ?", + "render": "Cet endroit s'appelle {nom}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Cet endroit a une station de vidange sanitaire" + }, + "1": { + "then": "Ce site ne possède pas de lieu de vidange" + } + }, + "question": "Ce site possède-t’il un lieu de vidange ?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Ce site a des toilettes" + }, + "1": { + "then": "Ce site n’a pas de toilettes" + } + }, + "question": "Y-a-t’il des toilettes sur le site ?" + }, + "caravansites-website": { + "question": "Ce lieu a-t’il un site internet ?", + "render": "Site officiel : {website}" } }, "title": { @@ -225,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Ce site demande un paiement" - }, - "1": { - "then": "Ce site ne demande pas de paiement" - } - }, - "question": "Ce site est-il payant ?" - }, - "2": { - "question": "Combien ce site demande t’il de payer ?", - "render": "Ce site fait payer {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "Ce site a un point d’eau" - }, - "1": { - "then": "Ce site n’a pas de point d’eau" - } - }, - "question": "Ce site dispose-t’il d’un point d’eau ?" - }, - "4": { - "mappings": { - "0": { - "then": "Il est possible d’y vidanger ses eaux usées" - }, - "1": { - "then": "Il n’est pas possible d’y vidanger ses eaux usées" - } - }, - "question": "Est-il possible d’y faire sa vidange des eaux usées ?" - }, - "5": { - "mappings": { - "0": { - "then": "Il est possible d’y vidanger ses toilettes chimiques" - }, - "1": { - "then": "Il n’est pas possible d’y vidanger ses toilettes chimiques" - } - }, - "question": "Est-il possible d’y vidanger ses toilettes chimiques ?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "Un code est nécessaire" @@ -290,9 +237,57 @@ }, "question": "Qui peut utiliser le site de vidange ?" }, - "7": { + "dumpstations-charge": { + "question": "Combien ce site demande t’il de payer ?", + "render": "Ce site fait payer {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "Il est possible d’y vidanger ses toilettes chimiques" + }, + "1": { + "then": "Il n’est pas possible d’y vidanger ses toilettes chimiques" + } + }, + "question": "Est-il possible d’y vidanger ses toilettes chimiques ?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "Ce site demande un paiement" + }, + "1": { + "then": "Ce site ne demande pas de paiement" + } + }, + "question": "Ce site est-il payant ?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Il est possible d’y vidanger ses eaux usées" + }, + "1": { + "then": "Il n’est pas possible d’y vidanger ses eaux usées" + } + }, + "question": "Est-il possible d’y faire sa vidange des eaux usées ?" + }, + "dumpstations-network": { "question": "De quel réseau fait-elle partie ? (Passer si aucun)", "render": "Cette station fait parte d’un réseau {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "Ce site a un point d’eau" + }, + "1": { + "then": "Ce site n’a pas de point d’eau" + } + }, + "question": "Ce site dispose-t’il d’un point d’eau ?" } }, "title": { @@ -343,7 +338,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "question": "Quel est le nom du club ou de l’association ?", "render": "{name}" } @@ -361,7 +356,7 @@ "description": "Une salle d’escalade", "name": "Salle d’escalade", "tagRenderings": { - "3": { + "name": { "question": "Quel est le nom de la salle d’escalade ?", "render": "{name}" } @@ -383,24 +378,7 @@ } }, "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "Cette voie n’a pas de nom" - } - }, - "question": "Quel est le nom de cette voie d’escalade ?", - "render": "{name}" - }, - "4": { - "question": "Quelle est la longueur de cette voie (en mètres) ?", - "render": "Cette voie fait {canonical(climbing:length)} de long" - }, - "5": { - "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", - "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" - }, - "6": { + "Bolts": { "mappings": { "0": { "then": "Cette voie n’a pas de prises" @@ -412,7 +390,24 @@ "question": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", "render": "Cette voie a {climbing:bolts} prises" }, - "8": { + "Difficulty": { + "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", + "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" + }, + "Length": { + "question": "Quelle est la longueur de cette voie (en mètres) ?", + "render": "Cette voie fait {canonical(climbing:length)} de long" + }, + "Name": { + "mappings": { + "0": { + "then": "Cette voie n’a pas de nom" + } + }, + "question": "Quel est le nom de cette voie d’escalade ?", + "render": "{name}" + }, + "Rock type": { "render": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" } }, @@ -435,25 +430,25 @@ } }, "tagRenderings": { - "3": { - "render": "

Résumé de longueur

{histogram(_length_hist)}" - }, - "4": { - "render": "

Résumé des difficultés

{histogram(_difficulty_hist)}" - }, - "5": { + "Containe {_contained_climbing_routes_count} routes": { "render": "

Contient {_contained_climbing_routes_count} voies

    {_contained_climbing_routes}
" }, - "6": { + "Contained routes hist": { + "render": "

Résumé des difficultés

{histogram(_difficulty_hist)}" + }, + "Contained routes length hist": { + "render": "

Résumé de longueur

{histogram(_length_hist)}" + }, + "Rock type (crag/rock/cliff only)": { "mappings": { "0": { - "then": "Ce site n’a pas de nom" + "then": "Calcaire" } }, - "question": "Quel est le nom de ce site ?", - "render": "{name}" + "question": "Quel est le type de roche ?", + "render": "La roche est du {rock}" }, - "7": { + "Type": { "mappings": { "0": { "then": "Rocher d’escalade, rocher avec une ou peu de voie permettant d’escalader sans corde" @@ -463,14 +458,14 @@ } } }, - "8": { + "name": { "mappings": { "0": { - "then": "Calcaire" + "then": "Ce site n’a pas de nom" } }, - "question": "Quel est le type de roche ?", - "render": "La roche est du {rock}" + "question": "Quel est le nom de ce site ?", + "render": "{name}" } }, "title": { @@ -495,10 +490,10 @@ "description": "Opportunité d’escalade ?", "name": "Opportunités d’escalade ?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Escalader n’est pas possible" @@ -636,40 +631,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Détails supplémentaires sur le jardin (si nécessaire et non décrit précédemment)", + "render": "Plus de détails : {description}" + }, + "facadegardens-direction": { "question": "Quelle est l’orientation du jardin ?", "render": "Orientation : {direction} (0 pour le Nord et 90 pour l’Ouest)" }, - "2": { - "mappings": { - "0": { - "then": "Le jardin est en plein soleil" - }, - "1": { - "then": "Le jardin est partiellement ensoleillé" - }, - "2": { - "then": "Le jardin est à l’ombre" - } - }, - "question": "Quel est l’ensoleillement du jardin ?" - }, - "3": { - "mappings": { - "0": { - "then": "Il y a des réserves" - }, - "1": { - "then": "Il n’y a pas de réserves" - } - }, - "question": "Des réserves d’eau ont-elles été installées pour le jardin ?" - }, - "4": { - "question": "Quand le jardin a-t’il été construit ? (L’année suffit)", - "render": "Date de construction du jardin : {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Il y a des plantes comestibles" @@ -680,7 +650,7 @@ }, "question": "Y-a-t’il des plantes comestibles ?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Il y a des plantes grimpantes" @@ -697,9 +667,34 @@ }, "question": "Quel type de plantes pousse ici ?" }, - "7": { - "question": "Détails supplémentaires sur le jardin (si nécessaire et non décrit précédemment)", - "render": "Plus de détails : {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "Il y a des réserves" + }, + "1": { + "then": "Il n’y a pas de réserves" + } + }, + "question": "Des réserves d’eau ont-elles été installées pour le jardin ?" + }, + "facadegardens-start_date": { + "question": "Quand le jardin a-t’il été construit ? (L’année suffit)", + "render": "Date de construction du jardin : {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Le jardin est en plein soleil" + }, + "1": { + "then": "Le jardin est partiellement ensoleillé" + }, + "2": { + "then": "Le jardin est à l’ombre" + } + }, + "question": "Quel est l’ensoleillement du jardin ?" } }, "title": { @@ -737,7 +732,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "La borne est de couleur inconnue." @@ -752,7 +747,22 @@ "question": "Quelle est la couleur de la borne ?", "render": "La borne est {colour}" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "La borne est en état, ou partiellement en état, de fonctionner." + }, + "1": { + "then": "La borne est hors-service." + }, + "2": { + "then": "La borne a été retirée." + } + }, + "question": "Mettre à jour l’état de la borne.", + "render": "État" + }, + "hydrant-type": { "mappings": { "0": { "then": "La borne est de type inconnu." @@ -772,21 +782,6 @@ }, "question": "De quel type de borne s’agit-il ?", "render": " Type de borne : {fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "La borne est en état, ou partiellement en état, de fonctionner." - }, - "1": { - "then": "La borne est hors-service." - }, - "2": { - "then": "La borne a été retirée." - } - }, - "question": "Mettre à jour l’état de la borne.", - "render": "État" } }, "title": { @@ -803,7 +798,7 @@ } }, "tagRenderings": { - "0": { + "extinguisher-location": { "mappings": { "0": { "then": "Intérieur." @@ -830,19 +825,7 @@ } }, "tagRenderings": { - "0": { - "question": "Quel est le nom de la station ?", - "render": "Cette station s’appelle {name}." - }, - "1": { - "question": " Quel est le nom de la rue dans lequel elle se situe ?", - "render": "La station fait partie de la {addr:street}." - }, - "2": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "3": { + "station-agency": { "mappings": { "0": { "then": "Brigade de Protection du Feu" @@ -851,7 +834,11 @@ "question": "Quel est l’exploitant de la station ?", "render": "Cette station est opérée par {operator}." }, - "4": { + "station-name": { + "question": "Quel est le nom de la station ?", + "render": "Cette station s’appelle {name}." + }, + "station-operator": { "mappings": { "0": { "then": "La station est opérée par le gouvernement." @@ -868,6 +855,14 @@ }, "question": "Quel est le type d’exploitant ?", "render": "L’exploitant est de type {operator:type}." + }, + "station-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "station-street": { + "question": " Quel est le nom de la rue dans lequel elle se situe ?", + "render": "La station fait partie de la {addr:street}." } }, "title": { @@ -884,23 +879,15 @@ } }, "tagRenderings": { - "0": { - "question": "Quel est le nom de cette station ?", - "render": "Cette station s’appelle {name}." - }, - "1": { - "question": " Quel est le nom de la rue où la station se situe ?", - "render": "La station fait partie de {addr:street}." - }, - "2": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "3": { + "ambulance-agency": { "question": "Quel est l’exploitant de la station ?", "render": "Cette station est opérée par {operator}." }, - "4": { + "ambulance-name": { + "question": "Quel est le nom de cette station ?", + "render": "Cette station s’appelle {name}." + }, + "ambulance-operator-type": { "mappings": { "0": { "then": "La station est opérée par le gouvernement." @@ -917,6 +904,14 @@ }, "question": "Quel est le type d’exploitant ?", "render": "L’exploitant est de type {operator:type}." + }, + "ambulance-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "ambulance-street": { + "question": " Quel est le nom de la rue où la station se situe ?", + "render": "La station fait partie de {addr:street}." } }, "title": { @@ -943,23 +938,23 @@ } }, "tagRenderings": { - "0": { - "question": "Quel est la puissance générée par cette éolienne ?", - "render": "La puissance générée par cette éolienne est de {generator:output:electricity}." - }, - "1": { - "question": "Qui est l’exploitant de cette éolienne ?", - "render": "Cette éolienne est opérée par {operator}." - }, - "2": { - "question": "Quelle est la hauteur totale de l’éolienne en mètres, pales incluses ?", - "render": "La hauteur totale, incluant les pales, est de {height} mètres." - }, - "3": { + "turbine-diameter": { "question": "Quel est le diamètre du rotor en mètres ?", "render": "Le diamètre du rotor est de {rotor:diameter} mètres." }, - "4": { + "turbine-height": { + "question": "Quelle est la hauteur totale de l’éolienne en mètres, pales incluses ?", + "render": "La hauteur totale, incluant les pales, est de {height} mètres." + }, + "turbine-operator": { + "question": "Qui est l’exploitant de cette éolienne ?", + "render": "Cette éolienne est opérée par {operator}." + }, + "turbine-output": { + "question": "Quel est la puissance générée par cette éolienne ?", + "render": "La puissance générée par cette éolienne est de {generator:output:electricity}." + }, + "turbine-start-date": { "question": "Depuis quand l’éolienne est-elle en fonctionnement ?", "render": "L’éolienne est active depuis {start_date}." } @@ -1023,10 +1018,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Quelle est l'adresse électronique de ce magasin ?", + "render": "{email}" + }, + "shops-name": { "question": "Qu'est-ce que le nom de ce magasin?" }, - "2": { + "shops-opening_hours": { + "question": "Quels sont les horaires d'ouverture de ce magasin ?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "Quel est le numéro de téléphone ?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "Épicerie/superette" @@ -1053,21 +1060,9 @@ "question": "Que vends ce magasin ?", "render": "Ce magasin vends {shop}" }, - "3": { - "question": "Quel est le numéro de téléphone ?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "Quel est le site internet de ce magasin ?", "render": "{website}" - }, - "5": { - "question": "Quelle est l'adresse électronique de ce magasin ?", - "render": "{email}" - }, - "6": { - "question": "Quels sont les horaires d'ouverture de ce magasin ?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/id.json b/langs/themes/id.json index e95bb0454..7412ded69 100644 --- a/langs/themes/id.json +++ b/langs/themes/id.json @@ -9,7 +9,7 @@ "0": { "name": "Karya seni", "tagRenderings": { - "3": { + "artwork-website": { "render": "Info lanjut tersedia di laman web ini." } }, @@ -29,17 +29,14 @@ "layers": { "0": { "tagRenderings": { - "1": { - "question": "Apakah nama tempat ini?" - }, - "2": { + "caravansites-fee": { "mappings": { "1": { "then": "Boleh digunakan tanpa bayaran" } } }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Akses Web tersedia" @@ -53,7 +50,10 @@ }, "question": "Tempat ini berbagi akses Web?" }, - "8": { + "caravansites-name": { + "question": "Apakah nama tempat ini?" + }, + "caravansites-toilets": { "mappings": { "0": { "then": "Tempat sini ada tandas" @@ -63,7 +63,7 @@ } } }, - "9": { + "caravansites-website": { "question": "Tempat sini terada situs web?", "render": "Situs resmi: {website}" } @@ -90,35 +90,35 @@ "layers": { "0": { "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } } }, "1": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, "2": { "tagRenderings": { - "3": { + "Name": { "render": "{name}" } } }, "3": { "tagRenderings": { - "6": { + "name": { "render": "{name}" } } }, "4": { "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -129,7 +129,7 @@ "layers": { "0": { "tagRenderings": { - "1": { + "hydrant-type": { "mappings": { "3": { "then": " Jenis dinding." @@ -144,14 +144,14 @@ "layers": { "0": { "tagRenderings": { - "3": { + "shops-email": { + "render": "{email}" + }, + "shops-phone": { "render": "{phone}" }, - "4": { + "shops-website": { "render": "{website}" - }, - "5": { - "render": "{email}" } } } diff --git a/langs/themes/it.json b/langs/themes/it.json index e75545c57..ecac81814 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Quale artista ha creato quest’opera?", + "render": "Creato da {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architettura" @@ -57,15 +61,11 @@ "question": "Che tipo di opera d’arte è questo?", "render": "Si tratta di un {artwork_type}" }, - "2": { - "question": "Quale artista ha creato quest’opera?", - "render": "Creato da {artist_name}" - }, - "3": { + "artwork-website": { "question": "Esiste un sito web con maggiori informazioni su quest’opera?", "render": "Ulteriori informazioni su questo sito web" }, - "4": { + "artwork-wikidata": { "question": "Quale elemento Wikidata corrisponde a quest’opera d’arte?", "render": "Corrisponde a {wikidata}" } @@ -91,11 +91,6 @@ "description": "«Biciclette in prestito» è un luogo dove le biciclette possono essere prese in prestito, spesso in cambio di un piccolo contributo annuale. Un caso degno di nota è quello delle biciclette in prestito per bambini che permettono loro di cambiare le dimensioni della propria bici quando quella attuale diventa troppo piccola", "title": "Biciclette in prestito" }, - "bike_monitoring_stations": { - "description": "Questo tema mostra le stazioni di monitoraggio bici con dati dal vivo", - "shortDescription": "Stazioni di monitoraggio bici con dati in tempo reale forniti da Bruxelles Mobility", - "title": "Stazioni di monitoraggio biciclette" - }, "bookcases": { "description": "Una minibiblioteca è una piccola cabina a lato della strada, una scatola, una vecchia cabina telefonica o qualche altro contenitore che ospita libri. Tutti può lasciare o prendere un libro. Questa mappa punta a rappresentarle tutte. Puoi facilmente scoprire nuove minibiblioteche nelle tue vicinanze e, con un account gratuito su OpenStreetMap, puoi aggiungerne altre.", "title": "Mappa libera delle microbiblioteche" @@ -113,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Come viene chiamato questo luogo?", - "render": "Questo luogo è chiamato {name}" + "caravansites-capacity": { + "question": "Quanti camper possono stare qua? (non rispondere se non c’è un numero chario di spazi o veicoli ammessi)", + "render": "{capacity} camper possono usare questo luogo al contempo" }, - "2": { + "caravansites-charge": { + "question": "Quanto costa questo luogo?", + "render": "Questo luogo costa {charge}" + }, + "caravansites-description": { + "question": "Desideri aggiungere una descrizione del luogo? (Non vanno ripetute informazioni già richieste e mostrate precedentemente. Si prega di attenersi a dati oggettivi - le opinioni vanno nelle recensioni)", + "render": "Maggiori dettagli su questo luogo: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "Devi pagare per usarlo" @@ -128,26 +131,7 @@ }, "question": "Ha una tariffa questo luogo?" }, - "3": { - "question": "Quanto costa questo luogo?", - "render": "Questo luogo costa {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Questo luogo ha una stazione per lo scarico delle acque" - }, - "1": { - "then": "Questo luogo non ha una stazione per lo scarico delle acque" - } - }, - "question": "Questo luogo ha una stazione per lo scarico delle acque?" - }, - "5": { - "question": "Quanti camper possono stare qua? (non rispondere se non c’è un numero chario di spazi o veicoli ammessi)", - "render": "{capacity} camper possono usare questo luogo al contempo" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "C’è l’accesso a internet" @@ -161,7 +145,7 @@ }, "question": "Questo luogo ha l’accesso a internet?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "Occorre pagare un extra per avere l’accesso a internet" @@ -172,22 +156,7 @@ }, "question": "Occorre pagare per avere l’accesso a internet?" }, - "8": { - "mappings": { - "0": { - "then": "Questo luogo ha i servizi igienici" - }, - "1": { - "then": "Questo luogo non ha i servizi igienici" - } - }, - "question": "Questo luogo dispone di servizi igienici?" - }, - "9": { - "question": "Questo luogo ha un sito web?", - "render": "Sito web ufficiale: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Sì, ci sono spazi per il noleggio a lungo termine, ma puoi anche pagare per singola giornata" @@ -201,9 +170,35 @@ }, "question": "Questo luogo offre spazi per il noleggio a lungo termine?" }, - "11": { - "question": "Desideri aggiungere una descrizione del luogo? (Non vanno ripetute informazioni già richieste e mostrate precedentemente. Si prega di attenersi a dati oggettivi - le opinioni vanno nelle recensioni)", - "render": "Maggiori dettagli su questo luogo: {description}" + "caravansites-name": { + "question": "Come viene chiamato questo luogo?", + "render": "Questo luogo è chiamato {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Questo luogo ha una stazione per lo scarico delle acque" + }, + "1": { + "then": "Questo luogo non ha una stazione per lo scarico delle acque" + } + }, + "question": "Questo luogo ha una stazione per lo scarico delle acque?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Questo luogo ha i servizi igienici" + }, + "1": { + "then": "Questo luogo non ha i servizi igienici" + } + }, + "question": "Questo luogo dispone di servizi igienici?" + }, + "caravansites-website": { + "question": "Questo luogo ha un sito web?", + "render": "Sito web ufficiale: {website}" } }, "title": { @@ -225,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "A pagamento" - }, - "1": { - "then": "È gratuito" - } - }, - "question": "Questo luogo è a pagamento?" - }, - "2": { - "question": "Qual è la tariffa di questo luogo?", - "render": "Ha una tariffa di {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "Questo luogo ha un punto per l'approvvigionamento di acqua" - }, - "1": { - "then": "Questo luogo non ha un punto per l'approvvigionamento di acqua" - } - }, - "question": "Questo luogo ha un punto per l'approvvigionamento di acqua?" - }, - "4": { - "mappings": { - "0": { - "then": "Si possono smaltire le acque grigie qui" - }, - "1": { - "then": "Non si possono smaltire le acque grigie qui" - } - }, - "question": "Si possono smaltire le acque grigie qui?" - }, - "5": { - "mappings": { - "0": { - "then": "È possibile smaltire le acque del WC chimico qui" - }, - "1": { - "then": "Non è possibile smaltire le acque del WC chimico qui" - } - }, - "question": "È possibile smaltire le acque del WC chimico qui?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "Servono una chiave o un codice di accesso" @@ -290,9 +237,57 @@ }, "question": "Chi può utilizzare questo luogo di sversamento?" }, - "7": { + "dumpstations-charge": { + "question": "Qual è la tariffa di questo luogo?", + "render": "Ha una tariffa di {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "È possibile smaltire le acque del WC chimico qui" + }, + "1": { + "then": "Non è possibile smaltire le acque del WC chimico qui" + } + }, + "question": "È possibile smaltire le acque del WC chimico qui?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "A pagamento" + }, + "1": { + "then": "È gratuito" + } + }, + "question": "Questo luogo è a pagamento?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Si possono smaltire le acque grigie qui" + }, + "1": { + "then": "Non si possono smaltire le acque grigie qui" + } + }, + "question": "Si possono smaltire le acque grigie qui?" + }, + "dumpstations-network": { "question": "Di quale rete fa parte questo luogo? (se non fa parte di nessuna rete, salta)", "render": "Questo luogo è parte della rete {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "Questo luogo ha un punto per l'approvvigionamento di acqua" + }, + "1": { + "then": "Questo luogo non ha un punto per l'approvvigionamento di acqua" + } + }, + "question": "Questo luogo ha un punto per l'approvvigionamento di acqua?" } }, "title": { @@ -334,7 +329,15 @@ "layers": { "2": { "tagRenderings": { - "3": { + "Difficulty": { + "question": "Qual è la difficoltà di questa via di arrampicata nel sistema francese/belga?", + "render": "Il grado di difficoltà è {climbing:grade:french} nel sistema francese/belga" + }, + "Length": { + "question": "Quanto è lunga questa via di arrampicata (in metri)?", + "render": "Questo percorso è lungo {canonical(climbing:length)}" + }, + "Name": { "mappings": { "0": { "then": "Questa via di arrampicata non ha un nome" @@ -342,14 +345,6 @@ }, "question": "Come si chiama questa via di arrampicata?", "render": "{name}" - }, - "4": { - "question": "Quanto è lunga questa via di arrampicata (in metri)?", - "render": "Questo percorso è lungo {canonical(climbing:length)}" - }, - "5": { - "question": "Qual è la difficoltà di questa via di arrampicata nel sistema francese/belga?", - "render": "Il grado di difficoltà è {climbing:grade:french} nel sistema francese/belga" } }, "title": { @@ -422,35 +417,11 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Il giardino è completamente illuminato dal sole" - }, - "1": { - "then": "Il giardino è parzialmente in ombra" - }, - "2": { - "then": "Il giardino è in ombra" - } - }, - "question": "Il giardino è al sole o in ombra?" + "facadegardens-description": { + "question": "Altre informazioni per descrivere il giardino (se necessarie e non riportate qui sopra)", + "render": "Maggiori dettagli: {description}" }, - "3": { - "mappings": { - "0": { - "then": "C'è un contenitore per raccogliere la pioggia" - }, - "1": { - "then": "Non c'è un contenitore per raccogliere la pioggia" - } - } - }, - "4": { - "question": "Quando è stato realizzato il giardino? (è sufficiente l'anno)", - "render": "Data di realizzazione del giardino: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Ci sono piante commestibili" @@ -461,7 +432,7 @@ }, "question": "Ci sono piante commestibili?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Ci sono viti" @@ -478,9 +449,33 @@ }, "question": "Che tipi di piante sono presenti qui?" }, - "7": { - "question": "Altre informazioni per descrivere il giardino (se necessarie e non riportate qui sopra)", - "render": "Maggiori dettagli: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "C'è un contenitore per raccogliere la pioggia" + }, + "1": { + "then": "Non c'è un contenitore per raccogliere la pioggia" + } + } + }, + "facadegardens-start_date": { + "question": "Quando è stato realizzato il giardino? (è sufficiente l'anno)", + "render": "Data di realizzazione del giardino: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Il giardino è completamente illuminato dal sole" + }, + "1": { + "then": "Il giardino è parzialmente in ombra" + }, + "2": { + "then": "Il giardino è in ombra" + } + }, + "question": "Il giardino è al sole o in ombra?" } } } @@ -495,14 +490,14 @@ "layers": { "0": { "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "2": { "then": "L'idrante è rosso." } } }, - "1": { + "hydrant-type": { "mappings": { "0": { "then": "Il tipo di idrante è sconosciuto." @@ -517,11 +512,11 @@ "description": "Livello che mostra le caserme dei vigili del fuoco.", "name": "Mappa delle caserme dei vigili del fuoco", "tagRenderings": { - "0": { + "station-name": { "question": "Come si chiama questa caserma dei vigili del fuoco?", "render": "Questa caserma si chiama {name}." }, - "1": { + "station-street": { "question": " Qual è il nome della via in cui si trova la caserma?" } }, diff --git a/langs/themes/ja.json b/langs/themes/ja.json index 7e79f1844..5f12ec6cf 100644 --- a/langs/themes/ja.json +++ b/langs/themes/ja.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "どのアーティストが作ったんですか?", + "render": "作成者:{artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "建物" @@ -57,15 +61,11 @@ "question": "この作品の種類は何ですか?", "render": "これは{artwork_type}です" }, - "2": { - "question": "どのアーティストが作ったんですか?", - "render": "作成者:{artist_name}" - }, - "3": { + "artwork-website": { "question": "この作品についての詳しい情報はどのウェブサイトにありますか?", "render": "Webサイトに詳細情報がある" }, - "4": { + "artwork-wikidata": { "question": "このアートワークに関するWikidataのエントリーはどれですか?", "render": "{wikidata}に関連する" } @@ -91,11 +91,6 @@ "description": "自転車ライブラリは、少額の年間料金で自転車を借りられる場所です。注目すべきユースケースとしては、子供向けの自転車ライブラリで、子どもの成長にあわせて大きな自転車へ借り替えられます", "title": "自転車ライブラリ" }, - "bike_monitoring_stations": { - "description": "このテーマでは、ライブデータのある自転車監視ステーションを示します", - "shortDescription": "Brussels Mobilityのライブデータを使用した自転車モニタリングステーション", - "title": "自転車監視ステーション" - }, "bookcases": { "description": "公共の本棚とは、本が保管されている小さな街角のキャビネット、箱、古い電話のトランク、その他の物のことです。誰でも本を置いたり持ったりすることができます。このマップは、すべての公共の本棚を収集することを目的としています。近くで新しい本棚を見つけることができ、無料のOpenStreetMapアカウントを使えば、お気に入りの本棚を簡単に追加できます。", "title": "オープン本棚マップ" @@ -113,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "ここは何というところですか?", - "render": "この場所は {name} と呼ばれています" + "caravansites-capacity": { + "question": "ここには何人のキャンパーが泊まれますか?(許可された車両の数や駐車スペースが明らかでない場合は省略)", + "render": "{capacity} 人が同時に使用できます" }, - "2": { + "caravansites-charge": { + "question": "ここはいくらかかりますか?", + "render": "この場所は{charge} が必要" + }, + "caravansites-description": { + "question": "この場所の一般的な説明を追加しますか?(前に問い合わせた情報や上記の情報を繰り返し入力しないでください。客観的な意見はレビューに反映されます)", + "render": "この場所の詳細:{description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "使用料を支払う必要がある" @@ -128,26 +131,7 @@ }, "question": "ここは有料ですか?" }, - "3": { - "question": "ここはいくらかかりますか?", - "render": "この場所は{charge} が必要" - }, - "4": { - "mappings": { - "0": { - "then": "この場所には衛生的なゴミ捨て場がある" - }, - "1": { - "then": "この場所には衛生的なゴミ捨て場がない" - } - }, - "question": "この場所に衛生的なゴミ捨て場はありますか?" - }, - "5": { - "question": "ここには何人のキャンパーが泊まれますか?(許可された車両の数や駐車スペースが明らかでない場合は省略)", - "render": "{capacity} 人が同時に使用できます" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "インターネットアクセスがある" @@ -161,7 +145,7 @@ }, "question": "この場所はインターネットにアクセスできますか?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "インターネット接続には別途料金が必要です" @@ -172,22 +156,7 @@ }, "question": "インターネット接続にお金はかかりますか?" }, - "8": { - "mappings": { - "0": { - "then": "ここにはトイレがある" - }, - "1": { - "then": "ここにはトイレがない" - } - }, - "question": "ここにトイレはありますか?" - }, - "9": { - "question": "ここにはウェブサイトがありますか?", - "render": "公式Webサイト: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "はい、長期レンタルのスポットもあり、日常的に滞在することもできます" @@ -201,9 +170,35 @@ }, "question": "ここには長期レンタルのスポットがありますか?" }, - "11": { - "question": "この場所の一般的な説明を追加しますか?(前に問い合わせた情報や上記の情報を繰り返し入力しないでください。客観的な意見はレビューに反映されます)", - "render": "この場所の詳細:{description}" + "caravansites-name": { + "question": "ここは何というところですか?", + "render": "この場所は {name} と呼ばれています" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "この場所には衛生的なゴミ捨て場がある" + }, + "1": { + "then": "この場所には衛生的なゴミ捨て場がない" + } + }, + "question": "この場所に衛生的なゴミ捨て場はありますか?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "ここにはトイレがある" + }, + "1": { + "then": "ここにはトイレがない" + } + }, + "question": "ここにトイレはありますか?" + }, + "caravansites-website": { + "question": "ここにはウェブサイトがありますか?", + "render": "公式Webサイト: {website}" } }, "title": { @@ -225,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "使用料を支払う必要がある" - }, - "1": { - "then": "無料で使用可能" - } - }, - "question": "ここは有料ですか?" - }, - "2": { - "question": "ここはいくらかかりますか?", - "render": "この場所は{charge} が必要" - }, - "3": { - "mappings": { - "0": { - "then": "この場所には給水所がある" - }, - "1": { - "then": "この場所には給水所がない" - } - }, - "question": "この場所には給水所がありますか?" - }, - "4": { - "mappings": { - "0": { - "then": "ここで汚水(雑排水)を捨てることができます" - }, - "1": { - "then": "ここでは汚水(雑排水)を捨てることはできない" - } - }, - "question": "汚水(雑排水)はこちらで処分できますか?" - }, - "5": { - "mappings": { - "0": { - "then": "携帯トイレのゴミはここで処分できます" - }, - "1": { - "then": "ここでは携帯トイレの廃棄物を処分することはできません" - } - }, - "question": "携帯トイレのゴミはこちらで処分できますか?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "これを使用するには、ネットワークキー/コードが必要です" @@ -290,9 +237,57 @@ }, "question": "このゴミ捨て場は誰が使えるんですか?" }, - "7": { + "dumpstations-charge": { + "question": "ここはいくらかかりますか?", + "render": "この場所は{charge} が必要" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "携帯トイレのゴミはここで処分できます" + }, + "1": { + "then": "ここでは携帯トイレの廃棄物を処分することはできません" + } + }, + "question": "携帯トイレのゴミはこちらで処分できますか?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "使用料を支払う必要がある" + }, + "1": { + "then": "無料で使用可能" + } + }, + "question": "ここは有料ですか?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "ここで汚水(雑排水)を捨てることができます" + }, + "1": { + "then": "ここでは汚水(雑排水)を捨てることはできない" + } + }, + "question": "汚水(雑排水)はこちらで処分できますか?" + }, + "dumpstations-network": { "question": "ここは何のネットワークの一部ですか?(なければスキップ)", "render": "このステーションはネットワーク{network}の一部です" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "この場所には給水所がある" + }, + "1": { + "then": "この場所には給水所がない" + } + }, + "question": "この場所には給水所がありますか?" } }, "title": { @@ -348,7 +343,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "question": "この登山クラブやNGOの名前は何ですか?", "render": "{name}" } @@ -366,7 +361,7 @@ "description": "クライミングジム", "name": "クライミングジム", "tagRenderings": { - "3": { + "name": { "question": "このクライミングジムは何という名前ですか?", "render": "{name}" } @@ -383,7 +378,13 @@ "2": { "name": "登坂ルート", "tagRenderings": { - "3": { + "Difficulty": { + "render": "フランス/ベルギーのランク評価システムによると、{climbing:grade:french}の困難度です" + }, + "Length": { + "render": "このルート長は、 {canonical(climbing:length)} メーターです" + }, + "Name": { "mappings": { "0": { "then": "この登坂ルートには名前がありません" @@ -391,12 +392,6 @@ }, "question": "この登坂ルートの名前は何ですか?", "render": "{name}" - }, - "4": { - "render": "このルート長は、 {canonical(climbing:length)} メーターです" - }, - "5": { - "render": "フランス/ベルギーのランク評価システムによると、{climbing:grade:french}の困難度です" } }, "title": { @@ -418,7 +413,7 @@ } }, "tagRenderings": { - "6": { + "name": { "mappings": { "0": { "then": "この登坂教室には名前がついていない" @@ -436,10 +431,10 @@ "description": "登坂教室?", "name": "登坂教室?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "ここでは登ることができない" @@ -625,40 +620,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "庭園に関する追加の説明情報(必要な場合でまだ上記に記載されていない場合)", + "render": "詳細情報: {description}" + }, + "facadegardens-direction": { "question": "庭の向きはどうなっていますか?", "render": "方向: {direction} (0=N で 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "庭は日があたっている" - }, - "1": { - "then": "庭は部分的に日陰である" - }, - "2": { - "then": "庭は日陰である" - } - }, - "question": "庭は日陰ですか、日当たりがいいですか?" - }, - "3": { - "mappings": { - "0": { - "then": "雨樽がある" - }, - "1": { - "then": "雨樽はありません" - } - }, - "question": "庭に水桶が設置されているのですか?" - }, - "4": { - "question": "その庭園はいつ造られたのですか?(建設年で十分です)", - "render": "庭園の建設日: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "食用の植物がある" @@ -669,7 +639,7 @@ }, "question": "食用の植物はありますか?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "つるがある" @@ -686,9 +656,34 @@ }, "question": "ここではどんな植物が育つんですか?" }, - "7": { - "question": "庭園に関する追加の説明情報(必要な場合でまだ上記に記載されていない場合)", - "render": "詳細情報: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "雨樽がある" + }, + "1": { + "then": "雨樽はありません" + } + }, + "question": "庭に水桶が設置されているのですか?" + }, + "facadegardens-start_date": { + "question": "その庭園はいつ造られたのですか?(建設年で十分です)", + "render": "庭園の建設日: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "庭は日があたっている" + }, + "1": { + "then": "庭は部分的に日陰である" + }, + "2": { + "then": "庭は日陰である" + } + }, + "question": "庭は日陰ですか、日当たりがいいですか?" } }, "title": { @@ -716,7 +711,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "消火栓の色は不明です。" @@ -731,7 +726,22 @@ "question": "消火栓の色は何色ですか?", "render": "消火栓の色は{color}です" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "消火栓は(完全にまたは部分的に)機能しています。" + }, + "1": { + "then": "消火栓は使用できません。" + }, + "2": { + "then": "消火栓が撤去されました。" + } + }, + "question": "消火栓のライフサイクルステータスを更新します。", + "render": "ライフサイクルステータス" + }, + "hydrant-type": { "mappings": { "0": { "then": "消火栓の種類は不明です。" @@ -751,21 +761,6 @@ }, "question": "どんな消火栓なんですか?", "render": " 消火栓のタイプ:{fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "消火栓は(完全にまたは部分的に)機能しています。" - }, - "1": { - "then": "消火栓は使用できません。" - }, - "2": { - "then": "消火栓が撤去されました。" - } - }, - "question": "消火栓のライフサイクルステータスを更新します。", - "render": "ライフサイクルステータス" } }, "title": { @@ -782,7 +777,7 @@ } }, "tagRenderings": { - "0": { + "extinguisher-location": { "mappings": { "0": { "then": "屋内にある。" @@ -809,19 +804,7 @@ } }, "tagRenderings": { - "0": { - "question": "この消防署の名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "1": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - }, - "2": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "3": { + "station-agency": { "mappings": { "0": { "then": "消防局(消防庁)" @@ -830,7 +813,11 @@ "question": "このステーションを運営しているのはどこですか?", "render": "このステーションは{operator}によって運営されています。" }, - "4": { + "station-name": { + "question": "この消防署の名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "station-operator": { "mappings": { "0": { "then": "ステーションは自治体が運営する。" @@ -847,6 +834,14 @@ }, "question": "ステーションの運営の分類は?", "render": "運営者は、{operator:type} です。" + }, + "station-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "station-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" } }, "title": { @@ -863,23 +858,15 @@ } }, "tagRenderings": { - "0": { - "question": "この救急ステーションの名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "1": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - }, - "2": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "3": { + "ambulance-agency": { "question": "このステーションを運営しているのはどこですか?", "render": "このステーションは{operator}によって運営されています。" }, - "4": { + "ambulance-name": { + "question": "この救急ステーションの名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "ambulance-operator-type": { "mappings": { "0": { "then": "ステーションは自治体が運営する。" @@ -896,6 +883,14 @@ }, "question": "ステーションの運営の分類は?", "render": "運営者は、{operator:type} です。" + }, + "ambulance-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "ambulance-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" } }, "title": { @@ -933,10 +928,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "このお店のメールアドレスは何ですか?", + "render": "{email}" + }, + "shops-name": { "question": "このお店の名前は何ですか?" }, - "2": { + "shops-opening_hours": { + "question": "この店の営業時間は何時から何時までですか?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "電話番号は何番ですか?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "コンビニエンスストア" @@ -963,21 +970,9 @@ "question": "このお店では何を売っていますか?", "render": "こちらのお店では{shop}を販売しております" }, - "3": { - "question": "電話番号は何番ですか?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "このお店のホームページは何ですか?", "render": "{website}" - }, - "5": { - "question": "このお店のメールアドレスは何ですか?", - "render": "{email}" - }, - "6": { - "question": "この店の営業時間は何時から何時までですか?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/nb_NO.json b/langs/themes/nb_NO.json index 84792b812..f42affa6a 100644 --- a/langs/themes/nb_NO.json +++ b/langs/themes/nb_NO.json @@ -12,7 +12,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Hvilken artist lagde dette?", + "render": "Laget av {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Arkitektur" @@ -54,15 +58,11 @@ "question": "Hvilken type kunstverk er dette?", "render": "Dette er et kunstverk av typen {artwork_type}" }, - "2": { - "question": "Hvilken artist lagde dette?", - "render": "Laget av {artist_name}" - }, - "3": { + "artwork-website": { "question": "Finnes det en nettside med mer info om dette kunstverket?", "render": "Mer info er å finne på denne nettsiden" }, - "4": { + "artwork-wikidata": { "question": "Hvilken Wikipedia-oppføring samsvarer med dette kunstverket?", "render": "Samsvarer med {wikidata}" } @@ -84,18 +84,21 @@ "layers": { "0": { "tagRenderings": { - "2": { + "caravansites-charge": { + "question": "pø", + "render": "Dette stedet tar {charge}" + }, + "caravansites-description": { + "render": "Flere detaljer om dette stedet: {description}" + }, + "caravansites-fee": { "mappings": { "1": { "then": "Kan brukes gratis" } } }, - "3": { - "question": "pø", - "render": "Dette stedet tar {charge}" - }, - "8": { + "caravansites-toilets": { "mappings": { "0": { "then": "Dette stedet har toalettfasiliteter" @@ -106,12 +109,9 @@ }, "question": "Har dette stedet toaletter?" }, - "9": { + "caravansites-website": { "question": "Har dette stedet en nettside?", "render": "Offisiell nettside: {website}" - }, - "11": { - "render": "Flere detaljer om dette stedet: {description}" } } } @@ -135,7 +135,7 @@ "2": { "name": "Klatreruter", "tagRenderings": { - "4": { + "Length": { "render": "Denne ruten er {canonical(climbing:length)} lang" } }, @@ -159,7 +159,7 @@ "description": "En klatremulighet?", "name": "Klatremuligheter?", "tagRenderings": { - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Klatring er ikke mulig her" @@ -232,7 +232,7 @@ "layers": { "0": { "tagRenderings": { - "2": { + "facadegardens-sunshine": { "mappings": { "1": { "then": "Denne hagen er i delvis skygge" @@ -257,7 +257,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "question": "Hvilken farge har brannhydranten?", "render": "Brannhydranter er {colour}" } diff --git a/langs/themes/nl.json b/langs/themes/nl.json index a27d74960..e3220df4d 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -19,7 +19,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Welke kunstenaar creëerde dit kunstwerk?", + "render": "Gecreëerd door {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architectuur" @@ -61,15 +65,11 @@ "question": "Wat voor soort kunstwerk is dit?", "render": "Dit is een {artwork_type}" }, - "2": { - "question": "Welke kunstenaar creëerde dit kunstwerk?", - "render": "Gecreëerd door {artist_name}" - }, - "3": { + "artwork-website": { "question": "Is er een website met meer informatie over dit kunstwerk?", "render": "Meer informatie op deze website" }, - "4": { + "artwork-wikidata": { "question": "Welk Wikidata-item beschrijft dit kunstwerk?", "render": "Komt overeen met {wikidata}" } @@ -95,11 +95,6 @@ "description": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.", "title": "Fietsbibliotheken" }, - "bike_monitoring_stations": { - "description": "Dit thema toont fietstelstations met live data", - "shortDescription": "Fietstelstations met live data van Brussel Mobiliteit", - "title": "Fietstelstations" - }, "binoculars": { "description": "Een kaart met verrekijkers die op een vaste plaats zijn gemonteerd", "shortDescription": "Een kaart met publieke verrekijker", @@ -254,11 +249,11 @@ "description": "camperplaatsen", "name": "Camperplaatsen", "tagRenderings": { - "1": { - "question": "Wat is de naam van deze plaats?", - "render": "Deze plaats heet {name}" + "caravansites-charge": { + "question": "Hoeveel kost deze plaats?", + "render": "Deze plaats vraagt {charge}" }, - "2": { + "caravansites-fee": { "mappings": { "0": { "then": "Gebruik is betalend" @@ -269,11 +264,11 @@ }, "question": "Moet men betalen om deze camperplaats te gebruiken?" }, - "3": { - "question": "Hoeveel kost deze plaats?", - "render": "Deze plaats vraagt {charge}" + "caravansites-name": { + "question": "Wat is de naam van deze plaats?", + "render": "Deze plaats heet {name}" }, - "9": { + "caravansites-website": { "render": "Officiële website: : {website}" } }, @@ -312,7 +307,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "question": "Wat is de naam van deze klimclub?", "render": "{name}" } @@ -330,7 +325,7 @@ "description": "Een klimzaal", "name": "Klimzalen", "tagRenderings": { - "3": { + "name": { "question": "Wat is de naam van dit Klimzaal?", "render": "{name}" } @@ -352,7 +347,15 @@ } }, "tagRenderings": { - "3": { + "Difficulty": { + "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", + "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" + }, + "Length": { + "question": "Hoe lang is deze klimroute (in meters)?", + "render": "Deze klimroute is {canonical(climbing:length)} lang" + }, + "Name": { "mappings": { "0": { "then": "Deze klimroute heeft geen naam" @@ -360,14 +363,6 @@ }, "question": "Hoe heet deze klimroute?", "render": "{name}" - }, - "4": { - "question": "Hoe lang is deze klimroute (in meters)?", - "render": "Deze klimroute is {canonical(climbing:length)} lang" - }, - "5": { - "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", - "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" } }, "title": { @@ -389,7 +384,14 @@ } }, "tagRenderings": { - "6": { + "Rock type (crag/rock/cliff only)": { + "mappings": { + "0": { + "then": "Kalksteen" + } + } + }, + "name": { "mappings": { "0": { "then": "Dit Klimgelegenheid heeft geen naam" @@ -397,13 +399,6 @@ }, "question": "Wat is de naam van dit Klimgelegenheid?", "render": "{name}" - }, - "8": { - "mappings": { - "0": { - "then": "Kalksteen" - } - } } }, "title": { @@ -425,10 +420,10 @@ "description": "Een klimgelegenheid?", "name": "Klimgelegenheiden?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Klimmen is hier niet mogelijk" @@ -642,40 +637,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Aanvullende omschrijving van de tuin (indien nodig, en voor zover nog niet omschreven hierboven)", + "render": "Meer details: {description}" + }, + "facadegardens-direction": { "question": "Hoe is de tuin georiënteerd?", "render": "Oriëntatie: {direction} (waarbij 0=N en 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "Het is een volle zon tuintje" - }, - "1": { - "then": "Het is een halfschaduw tuintje" - }, - "2": { - "then": "Het is een schaduw tuintje" - } - }, - "question": "Ligt de tuin in zon/half schaduw of schaduw?" - }, - "3": { - "mappings": { - "0": { - "then": "Er is een regenton" - }, - "1": { - "then": "Er is geen regenton" - } - }, - "question": "Is er een regenton voorzien bij het tuintje?" - }, - "4": { - "question": "Wanneer werd de tuin aangelegd? (vul gewoon een jaartal in)", - "render": "Aanlegdatum van de tuin: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Er staan eetbare planten" @@ -686,7 +656,7 @@ }, "question": "Staan er eetbare planten?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Er staat een klimplant" @@ -703,9 +673,34 @@ }, "question": "Wat voor planten staan hier?" }, - "7": { - "question": "Aanvullende omschrijving van de tuin (indien nodig, en voor zover nog niet omschreven hierboven)", - "render": "Meer details: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "Er is een regenton" + }, + "1": { + "then": "Er is geen regenton" + } + }, + "question": "Is er een regenton voorzien bij het tuintje?" + }, + "facadegardens-start_date": { + "question": "Wanneer werd de tuin aangelegd? (vul gewoon een jaartal in)", + "render": "Aanlegdatum van de tuin: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Het is een volle zon tuintje" + }, + "1": { + "then": "Het is een halfschaduw tuintje" + }, + "2": { + "then": "Het is een schaduw tuintje" + } + }, + "question": "Ligt de tuin in zon/half schaduw of schaduw?" } }, "title": { @@ -756,21 +751,21 @@ } }, "tagRenderings": { - "0": { - "question": "Wat is de soort van deze boom (in het Nederlands)?", - "render": "De soort is {species:nl}" - }, - "1": { - "question": "Wat is het taxon (ras) van deze boom?", - "render": "Het ras (taxon) van deze boom is {taxon}" - }, - "2": { + "fruitboom-description": { "question": "Welke beschrijving past bij deze boom?", "render": "Beschrijving: {description}" }, - "3": { + "fruitboom-ref": { "question": "Is er een refernetienummer?", "render": "Referentienummer: {ref}" + }, + "fruitboom-species:nl": { + "question": "Wat is de soort van deze boom (in het Nederlands)?", + "render": "De soort is {species:nl}" + }, + "fruitboom-taxon": { + "question": "Wat is het taxon (ras) van deze boom?", + "render": "Het ras (taxon) van deze boom is {taxon}" } }, "title": { @@ -792,23 +787,7 @@ "description": "Dit gebouw heeft een foutmelding", "name": "Fixmes op gebouwen", "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Geen huisnummer" - } - }, - "question": "Wat is het huisnummer?", - "render": "Het huisnummer is {addr:housenumber}" - }, - "1": { - "render": "De wooneenheid-aanduiding is {addr:unit} " - }, - "2": { - "question": "Wat is de straat?", - "render": "De straat is {addr:street}" - }, - "3": { + "grb-fixme": { "mappings": { "0": { "then": "Geen fixme" @@ -817,9 +796,25 @@ "question": "Wat zegt de fixme?", "render": "De fixme is {fixme}" }, - "4": { + "grb-housenumber": { + "mappings": { + "0": { + "then": "Geen huisnummer" + } + }, + "question": "Wat is het huisnummer?", + "render": "Het huisnummer is {addr:housenumber}" + }, + "grb-min-level": { "question": "Hoeveel verdiepingen ontbreken?", "render": "Dit gebouw begint maar op de {building:min_level} verdieping" + }, + "grb-street": { + "question": "Wat is de straat?", + "render": "De straat is {addr:street}" + }, + "grb-unit": { + "render": "De wooneenheid-aanduiding is {addr:unit} " } }, "title": { @@ -926,10 +921,19 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Wat is het e-mailadres van deze winkel?" + }, + "shops-name": { "question": "Wat is de naam van deze winkel?" }, - "2": { + "shops-opening_hours": { + "question": "Wat zijn de openingsuren van deze winkel?" + }, + "shops-phone": { + "question": "Wat is het telefoonnummer?" + }, + "shops-shop": { "mappings": { "1": { "then": "Supermarkt" @@ -942,17 +946,8 @@ } } }, - "3": { - "question": "Wat is het telefoonnummer?" - }, - "4": { + "shops-website": { "question": "Wat is de website van deze winkel?" - }, - "5": { - "question": "Wat is het e-mailadres van deze winkel?" - }, - "6": { - "question": "Wat zijn de openingsuren van deze winkel?" } }, "title": { @@ -967,10 +962,20 @@ "7": { "name": "Wandelroutes van provincie Antwerpen", "tagRenderings": { - "0": { + "walk-description": { + "render": "

Korte beschrijving:

{description}" + }, + "walk-length": { "render": "Deze wandeling is {_length:km}km lang" }, - "1": { + "walk-operator": { + "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" + }, + "walk-operator-email": { + "question": "Naar wie kan men emailen bij problemen rond signalisatie?", + "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" + }, + "walk-type": { "mappings": { "0": { "then": "Dit is een internationale wandelroute" @@ -985,16 +990,6 @@ "then": "Dit is een lokale wandelroute" } } - }, - "2": { - "render": "

Korte beschrijving:

{description}" - }, - "3": { - "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "4": { - "question": "Naar wie kan men emailen bij problemen rond signalisatie?", - "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" } } } @@ -1002,47 +997,6 @@ "shortDescription": "Speelplekken in de Antwerpse Zuidrand", "title": "Welkom bij de groendoener!" }, - "speelplekken_temp": { - "description": "Speelplekken in de Antwerpse Zuidrand. Een project van Provincie Antwerpen, in samenwerking met Createlli, Sportpret en OpenStreetMap België", - "layers": { - "6": { - "name": "Wandelroutes van provincie Antwerpen", - "tagRenderings": { - "0": { - "render": "Deze wandeling is {_length:km}km lang" - }, - "1": { - "mappings": { - "0": { - "then": "Dit is een internationale wandelroute" - }, - "1": { - "then": "Dit is een nationale wandelroute" - }, - "2": { - "then": "Dit is een regionale wandelroute" - }, - "3": { - "then": "Dit is een lokale wandelroute" - } - } - }, - "2": { - "render": "

Korte beschrijving:

{description}" - }, - "3": { - "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "4": { - "question": "Naar wie kan men emailen bij problemen rond signalisatie?", - "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" - } - } - } - }, - "shortDescription": "Speelplekken in de Antwerpse Zuidrand", - "title": "Speelplekken in de Antwerpse Zuidrand" - }, "sport_pitches": { "description": "Een sportveld is een ingerichte plaats met infrastructuur om een sport te beoefenen", "shortDescription": "Deze kaart toont sportvelden", @@ -1054,7 +1008,7 @@ "title": "Surveillance under Surveillance" }, "toerisme_vlaanderen": { - "description": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen", + "description": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen", "shortDescription": "Een kaart om toeristisch relevante info op aan te duiden", "title": "Toeristisch relevante info" }, @@ -1071,23 +1025,5 @@ "description": "Op deze kaart vind je vuilnisbakken waar je afval in kan smijten. Ontbreekt er een vuilnisbak? Dan kan je die zelf toevoegen", "shortDescription": "Een kaart met vuilnisbakken", "title": "Vuilnisbak" - }, - "width": { - "description": "

De straat is opgebruikt

\n

Er is steeds meer druk op de openbare ruimte. Voetgangers, fietsers, steps, auto's, bussen, bestelwagens, buggies, cargobikes, ... willen allemaal hun deel van de openbare ruimte.

\n

In deze studie nemen we Brugge onder de loep en kijken we hoe breed elke straat is én hoe breed elke straat zou moeten zijn voor een veilig én vlot verkeer.

\n

Legende

\n     Straat te smal voor veilig verkeer
\n     Straat is breed genoeg veilig verkeer
\n     Straat zonder voetpad, te smal als ook voetgangers plaats krijgen
\n     Woonerf, autoluw, autoloos of enkel plaatselijk verkeer
\n
\n
\n Een gestippelde lijn is een straat waar ook voor fietsers éénrichtingsverkeer geldt.
\n Klik op een straat om meer informatie te zien.\n

Hoe gaan we verder?

\n Verschillende ingrepen kunnen de stad teruggeven aan de inwoners en de stad leefbaarder en levendiger maken.
\n Denk aan:\n
    \n
  • De autovrije zone's uitbreiden
  • \n
  • De binnenstad fietszone maken
  • \n
  • Het aantal woonerven uitbreiden
  • \n
  • Grotere auto's meer belasten - ze nemen immers meer parkeerruimte in.
  • \n
  • Laat toeristen verplicht parkeren onder het zand; een (fiets)taxi kan hen naar hun hotel brengen
  • \n
  • Voorzie in elke straat enkele parkeerplaatsen voor kortparkeren. Zo kunnen leveringen, iemand afzetten,... gebeuren zonder op het voetpad en fietspad te parkeren
  • \n
", - "layers": { - "0": { - "name": "Straten met een breedte", - "title": { - "mappings": { - "0": { - "then": "Naamloos segmet" - } - }, - "render": "{name}" - } - } - }, - "shortDescription": "Is de straat breed genoeg?", - "title": "Straatbreedtes" } } \ No newline at end of file diff --git a/langs/themes/pt.json b/langs/themes/pt.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/langs/themes/pt.json @@ -0,0 +1 @@ +{} diff --git a/langs/themes/pt_BR.json b/langs/themes/pt_BR.json index 56138ae8f..6c7de8bfd 100644 --- a/langs/themes/pt_BR.json +++ b/langs/themes/pt_BR.json @@ -10,11 +10,6 @@ "bicyclelib": { "title": "Bibliotecas de bicicletas" }, - "bike_monitoring_stations": { - "description": "Este tema mostra as estações de monitoramento de bicicletas com dados ao vivo", - "shortDescription": "Estações de monitoramento de bicicletas com dados ao vivo da Mobilidade de Bruxelas", - "title": "Estações de monitoramento de bicicletas" - }, "bookcases": { "title": "Abrir Mapa de Estantes" }, @@ -29,11 +24,18 @@ } }, "tagRenderings": { - "1": { - "question": "Qual o nome deste lugar?", - "render": "Este lugar é chamado de {name}" + "caravansites-capacity": { + "question": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)", + "render": "{capacity} campistas podem usar este lugar ao mesmo tempo" }, - "2": { + "caravansites-charge": { + "question": "Quanto este lugar cobra?", + "render": "Este lugar cobra {charge}" + }, + "caravansites-description": { + "render": "Mais detalhes sobre este lugar: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "Você precisa pagar para usar" @@ -44,26 +46,7 @@ }, "question": "Este lugar cobra alguma taxa?" }, - "3": { - "question": "Quanto este lugar cobra?", - "render": "Este lugar cobra {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Este local tem uma estação de aterro sanitário" - }, - "1": { - "then": "Este local não tem uma estação de aterro sanitário" - } - }, - "question": "Este local tem uma estação de aterro sanitário?" - }, - "5": { - "question": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)", - "render": "{capacity} campistas podem usar este lugar ao mesmo tempo" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Há acesso à internet" @@ -77,7 +60,7 @@ }, "question": "Este lugar fornece acesso a internet?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "Você precisa pagar um extra pelo acesso à internet" @@ -88,22 +71,7 @@ }, "question": "Você tem que pagar pelo acesso à internet?" }, - "8": { - "mappings": { - "0": { - "then": "Este lugar tem banheiros" - }, - "1": { - "then": "Este lugar não tem banheiros" - } - }, - "question": "Este lugar tem banheiros?" - }, - "9": { - "question": "Este lugar tem um website?", - "render": "Site oficial: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Sim, há alguns pontos para aluguel a longo prazo, mas você também pode ficar em uma base diária" @@ -114,8 +82,35 @@ }, "question": "Este lugar oferece vagas para aluguel a longo prazo?" }, - "11": { - "render": "Mais detalhes sobre este lugar: {description}" + "caravansites-name": { + "question": "Qual o nome deste lugar?", + "render": "Este lugar é chamado de {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Este local tem uma estação de aterro sanitário" + }, + "1": { + "then": "Este local não tem uma estação de aterro sanitário" + } + }, + "question": "Este local tem uma estação de aterro sanitário?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Este lugar tem banheiros" + }, + "1": { + "then": "Este lugar não tem banheiros" + } + }, + "question": "Este lugar tem banheiros?" + }, + "caravansites-website": { + "question": "Este lugar tem um website?", + "render": "Site oficial: {website}" } }, "title": { @@ -131,7 +126,11 @@ "description": "Estações de despejo sanitário", "name": "Estações de despejo sanitário", "tagRenderings": { - "1": { + "dumpstations-charge": { + "question": "Quanto este lugar cobra?", + "render": "Este lugar cobra {charge}" + }, + "dumpstations-fee": { "mappings": { "0": { "then": "Você precisa pagar pelo uso" @@ -142,11 +141,7 @@ }, "question": "Este lugar cobra alguma taxa?" }, - "2": { - "question": "Quanto este lugar cobra?", - "render": "Este lugar cobra {charge}" - }, - "3": { + "dumpstations-waterpoint": { "mappings": { "0": { "then": "Este lugar tem um ponto de água" diff --git a/langs/themes/ru.json b/langs/themes/ru.json index e4168c08d..d03cdc427 100644 --- a/langs/themes/ru.json +++ b/langs/themes/ru.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Какой художник создал это?", + "render": "Создано {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Архитектура" @@ -57,15 +61,11 @@ "question": "К какому типу относится эта работа?", "render": "Это {artwork_type}" }, - "2": { - "question": "Какой художник создал это?", - "render": "Создано {artist_name}" - }, - "3": { + "artwork-website": { "question": "Есть ли сайт с более подробной информацией об этой работе?", "render": "Больше информации на этом сайте" }, - "4": { + "artwork-wikidata": { "question": "Какая запись в Wikidata соответсвует этой работе?", "render": "Запись об этой работе в wikidata: {wikidata}" } @@ -91,11 +91,6 @@ "description": "Велосипедная библиотека - это место, где велосипеды можно взять на время, часто за небольшую ежегодную плату. Примером использования являются библиотеки велосипедов для детей, что позволяет им сменить велосипед на больший, когда они перерастают свой нынешний велосипед", "title": "Велосипедные библиотеки" }, - "bike_monitoring_stations": { - "description": "В этой теме показаны станции мониторинга велосипедов с данными в реальном времени", - "shortDescription": "Станции мониторинга велосипедов с оперативными данными от Brussels Mobility", - "title": "Станции мониторинга велосипедов" - }, "bookcases": { "description": "Общественный книжный шкаф - это небольшой уличный шкаф, коробка, старый телефонный аппарат или другие предметы, где хранятся книги. Каждый может положить или взять книгу. Цель этой карты - собрать все эти книжные шкафы. Вы можете обнаружить новые книжные шкафы поблизости и, имея бесплатный аккаунт OpenStreetMap, быстро добавить свои любимые книжные шкафы.", "title": "Открытая карта книжных шкафов" @@ -113,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется это место?", - "render": "Это место называется {name}" + "caravansites-capacity": { + "question": "Сколько кемперов может здесь остановиться? (пропустите, если нет очевидного количества мест или разрешённых транспортных средств)", + "render": "{capacity} кемперов могут использовать это место одновременно" }, - "2": { + "caravansites-charge": { + "question": "Сколько это место взимает?", + "render": "Это место взимает {charge}" + }, + "caravansites-description": { + "question": "Хотели бы вы добавить общее описание этого места? (Не повторяйте информацию, которая уже написана выше или на которую вы уже ответили ранее. Пожалуйста, будьте объективны - мнения должны быть в отзывах)", + "render": "Более подробная информация об этом месте: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "За использование нужно платить" @@ -128,26 +131,7 @@ }, "question": "Взимается ли в этом месте плата?" }, - "3": { - "question": "Сколько это место взимает?", - "render": "Это место взимает {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "В этом кемпинге есть место для слива отходов из туалетных резервуаров" - }, - "1": { - "then": "В этом кемпинге нет места для слива отходов из туалетных резервуаров" - } - }, - "question": "В этом кемпинге есть место для слива отходов из туалетных резервуаров?" - }, - "5": { - "question": "Сколько кемперов может здесь остановиться? (пропустите, если нет очевидного количества мест или разрешённых транспортных средств)", - "render": "{capacity} кемперов могут использовать это место одновременно" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Есть доступ в Интернет" @@ -161,7 +145,7 @@ }, "question": "Предоставляет ли это место доступ в Интернет?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "За доступ в Интернет нужно платить дополнительно" @@ -172,22 +156,7 @@ }, "question": "Нужно ли платить за доступ в Интернет?" }, - "8": { - "mappings": { - "0": { - "then": "В этом месте есть туалеты" - }, - "1": { - "then": "В этом месте нет туалетов" - } - }, - "question": "Здесь есть туалеты?" - }, - "9": { - "question": "Есть ли у этого места веб-сайт?", - "render": "Официальный сайт: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Да, здесь есть места для долгосрочной аренды, но вы можете остановиться и на сутки" @@ -201,9 +170,35 @@ }, "question": "Предлагает ли эта площадка места для долгосрочной аренды?" }, - "11": { - "question": "Хотели бы вы добавить общее описание этого места? (Не повторяйте информацию, которая уже написана выше или на которую вы уже ответили ранее. Пожалуйста, будьте объективны - мнения должны быть в отзывах)", - "render": "Более подробная информация об этом месте: {description}" + "caravansites-name": { + "question": "Как называется это место?", + "render": "Это место называется {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "В этом кемпинге есть место для слива отходов из туалетных резервуаров" + }, + "1": { + "then": "В этом кемпинге нет места для слива отходов из туалетных резервуаров" + } + }, + "question": "В этом кемпинге есть место для слива отходов из туалетных резервуаров?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "В этом месте есть туалеты" + }, + "1": { + "then": "В этом месте нет туалетов" + } + }, + "question": "Здесь есть туалеты?" + }, + "caravansites-website": { + "question": "Есть ли у этого места веб-сайт?", + "render": "Официальный сайт: {website}" } }, "title": { @@ -219,55 +214,7 @@ "description": "Ассенизационные сливные станции", "name": "Места для слива отходов из туалетных резервуаров", "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "За использование нужно платить" - }, - "1": { - "then": "Можно использовать бесплатно" - } - }, - "question": "Взимается ли в этом месте плата?" - }, - "2": { - "question": "Сколько это место взимает?", - "render": "Это место взимает {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "В этом месте есть водоснабжение" - }, - "1": { - "then": "В этом месте нет водоснабжения" - } - }, - "question": "Есть ли в этом месте водоснабжение?" - }, - "4": { - "mappings": { - "0": { - "then": "Вы можете утилизировать серую воду здесь" - }, - "1": { - "then": "Здесь нельзя утилизировать серую воду" - } - }, - "question": "Можно ли здесь утилизировать серую воду?" - }, - "5": { - "mappings": { - "0": { - "then": "Вы можете утилизировать отходы химических туалетов здесь" - }, - "1": { - "then": "Здесь нельзя утилизировать отходы химических туалетов" - } - }, - "question": "Можно ли здесь утилизировать отходы химических туалетов?" - }, - "6": { + "dumpstations-access": { "mappings": { "2": { "then": "Любой может воспользоваться этой станцией утилизации" @@ -278,9 +225,57 @@ }, "question": "Кто может использовать эту станцию утилизации?" }, - "7": { + "dumpstations-charge": { + "question": "Сколько это место взимает?", + "render": "Это место взимает {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "Вы можете утилизировать отходы химических туалетов здесь" + }, + "1": { + "then": "Здесь нельзя утилизировать отходы химических туалетов" + } + }, + "question": "Можно ли здесь утилизировать отходы химических туалетов?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "За использование нужно платить" + }, + "1": { + "then": "Можно использовать бесплатно" + } + }, + "question": "Взимается ли в этом месте плата?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Вы можете утилизировать серую воду здесь" + }, + "1": { + "then": "Здесь нельзя утилизировать серую воду" + } + }, + "question": "Можно ли здесь утилизировать серую воду?" + }, + "dumpstations-network": { "question": "К какой сети относится эта станция? (пропустите, если неприменимо)", "render": "Эта станция - часть сети {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "В этом месте есть водоснабжение" + }, + "1": { + "then": "В этом месте нет водоснабжения" + } + }, + "question": "Есть ли в этом месте водоснабжение?" } }, "title": { @@ -312,7 +307,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } }, @@ -322,28 +317,28 @@ }, "1": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, "2": { "tagRenderings": { - "3": { + "Name": { "render": "{name}" } } }, "3": { "tagRenderings": { - "6": { + "name": { "render": "{name}" } } }, "4": { "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -394,10 +389,14 @@ "layers": { "0": { "tagRenderings": { - "2": { - "question": "Сад расположен на солнечной стороне или в тени?" + "facadegardens-description": { + "question": "Дополнительная информация о саде (если требуется или еще не указана выше)", + "render": "Подробнее: {description}" }, - "3": { + "facadegardens-plants": { + "question": "Какие виды растений обитают здесь?" + }, + "facadegardens-rainbarrel": { "mappings": { "0": { "then": "Есть бочка с дождевой водой" @@ -407,15 +406,11 @@ } } }, - "4": { + "facadegardens-start_date": { "render": "Дата строительства сада: {start_date}" }, - "6": { - "question": "Какие виды растений обитают здесь?" - }, - "7": { - "question": "Дополнительная информация о саде (если требуется или еще не указана выше)", - "render": "Подробнее: {description}" + "facadegardens-sunshine": { + "question": "Сад расположен на солнечной стороне или в тени?" } } } @@ -435,7 +430,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "Цвет гидранта не определён." @@ -450,7 +445,17 @@ "question": "Какого цвета гидрант?", "render": "Цвет гидранта {colour}" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "Гидрант (полностью или частично) в рабочем состоянии." + }, + "2": { + "then": "Гидрант демонтирован." + } + } + }, + "hydrant-type": { "mappings": { "0": { "then": "Тип гидранта не определён." @@ -461,16 +466,6 @@ }, "question": "К какому типу относится этот гидрант?", "render": " Тип гидранта: {fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "Гидрант (полностью или частично) в рабочем состоянии." - }, - "2": { - "then": "Гидрант демонтирован." - } - } } }, "title": { @@ -487,7 +482,7 @@ } }, "tagRenderings": { - "0": { + "extinguisher-location": { "mappings": { "0": { "then": "Внутри." @@ -513,17 +508,17 @@ } }, "tagRenderings": { - "0": { + "station-name": { "question": "Как называется эта пожарная часть?", "render": "Эта часть называется {name}." }, - "1": { - "question": " По какому адресу расположена эта часть?", - "render": "Часть расположена вдоль шоссе {addr:street}." - }, - "2": { + "station-place": { "question": "Где расположена часть? (напр., название населённого пункта)", "render": "Эта часть расположена в {addr:place}." + }, + "station-street": { + "question": " По какому адресу расположена эта часть?", + "render": "Часть расположена вдоль шоссе {addr:street}." } }, "title": { @@ -539,16 +534,16 @@ } }, "tagRenderings": { - "0": { + "ambulance-name": { "question": "Как называется эта станция скорой помощи?", "render": "Эта станция называется {name}." }, - "1": { + "ambulance-place": { + "question": "Где расположена станция? (напр., название населённого пункта)" + }, + "ambulance-street": { "question": " По какому адресу расположена эта станция?", "render": "Эта станция расположена вдоль шоссе {addr:street}." - }, - "2": { - "question": "Где расположена станция? (напр., название населённого пункта)" } }, "title": { @@ -582,10 +577,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Каков адрес электронной почты этого магазина?", + "render": "{email}" + }, + "shops-name": { "question": "Как называется этот магазин?" }, - "2": { + "shops-opening_hours": { + "question": "Каковы часы работы этого магазина?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "Какой телефон?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "1": { "then": "Супермаркет" @@ -602,21 +609,9 @@ }, "question": "Что продаётся в этом магазине?" }, - "3": { - "question": "Какой телефон?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "Какой веб-сайт у этого магазина?", "render": "{website}" - }, - "5": { - "question": "Каков адрес электронной почты этого магазина?", - "render": "{email}" - }, - "6": { - "question": "Каковы часы работы этого магазина?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/zh_Hant.json b/langs/themes/zh_Hant.json index d60830222..4464b762f 100644 --- a/langs/themes/zh_Hant.json +++ b/langs/themes/zh_Hant.json @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "創造這個的藝術家是誰?", + "render": "{artist_name} 創作" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "建築物" @@ -57,15 +61,11 @@ "question": "這是什麼類型的藝術品?", "render": "這是 {artwork_type}" }, - "2": { - "question": "創造這個的藝術家是誰?", - "render": "{artist_name} 創作" - }, - "3": { + "artwork-website": { "question": "在那個網站能夠找到更多藝術品的資訊?", "render": "這個網站有更多資訊" }, - "4": { + "artwork-wikidata": { "question": "這個藝術品有那個對應的 Wikidata 項目?", "render": "與 {wikidata}對應" } @@ -91,11 +91,6 @@ "description": "單車圖書館是指每年支付小額費用,然後可以租用單車的地方。最有名的單車圖書館案例是給小孩的,能夠讓長大的小孩用目前的單車換成比較大的單車", "title": "單車圖書館" }, - "bike_monitoring_stations": { - "description": "這個主題顯示單車監視站的即時資料", - "shortDescription": "布魯塞爾車行資料的即時單車監視站資料", - "title": "自行車監視站" - }, "bookcases": { "description": "公共書架是街邊箱子、盒子、舊的電話亭或是其他存放書本的物件,每一個人都能放置或拿取書本。這份地圖收集所有類型的書架,你可以探索你附近新的書架,同時也能用免費的開放街圖帳號來快速新增你最愛的書架。", "title": "開放書架地圖" @@ -112,11 +107,19 @@ } }, "tagRenderings": { - "1": { - "question": "這個地方叫做什麼?", - "render": "這個地方叫做 {name}" + "caravansites-capacity": { + "question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)", + "render": "{capacity} 露營者能夠同時使用這個地方" }, - "2": { + "caravansites-charge": { + "question": "這個地方收多少費用?", + "render": "這個地方收費 {charge}" + }, + "caravansites-description": { + "question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)", + "render": "這個地方更詳細的資訊: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "你要付費才能使用" @@ -127,26 +130,7 @@ }, "question": "這個地方收費嗎?" }, - "3": { - "question": "這個地方收多少費用?", - "render": "這個地方收費 {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "這個地方有衛生設施" - }, - "1": { - "then": "這個地方沒有衛生設施" - } - }, - "question": "這個地方有衛生設施嗎?" - }, - "5": { - "question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)", - "render": "{capacity} 露營者能夠同時使用這個地方" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "這裡有網路連線" @@ -160,7 +144,7 @@ }, "question": "這個地方有提網路連線嗎?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "你需要額外付費來使用網路連線" @@ -171,22 +155,7 @@ }, "question": "你需要為網路連線付費嗎?" }, - "8": { - "mappings": { - "0": { - "then": "這個地方有廁所" - }, - "1": { - "then": "這個地方並沒有廁所" - } - }, - "question": "這個地方有廁所嗎?" - }, - "9": { - "question": "這個地方有網站嗎?", - "render": "官方網站:{website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "有,這個地方有提供長期租用,但你也可以用天計算費用" @@ -200,9 +169,35 @@ }, "question": "這個地方有提供長期租用嗎?" }, - "11": { - "question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)", - "render": "這個地方更詳細的資訊: {description}" + "caravansites-name": { + "question": "這個地方叫做什麼?", + "render": "這個地方叫做 {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "這個地方有衛生設施" + }, + "1": { + "then": "這個地方沒有衛生設施" + } + }, + "question": "這個地方有衛生設施嗎?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "這個地方有廁所" + }, + "1": { + "then": "這個地方並沒有廁所" + } + }, + "question": "這個地方有廁所嗎?" + }, + "caravansites-website": { + "question": "這個地方有網站嗎?", + "render": "官方網站:{website}" } }, "title": { @@ -216,7 +211,7 @@ }, "1": { "tagRenderings": { - "5": { + "dumpstations-chemical-waste": { "mappings": { "0": { "then": "你可以在這邊丟棄廁所化學廢棄物" @@ -246,7 +241,7 @@ "description": "攀岩社團或組織", "name": "攀岩社團", "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } }, diff --git a/preferences.ts b/preferences.ts index 310892003..c96912b5d 100644 --- a/preferences.ts +++ b/preferences.ts @@ -10,9 +10,17 @@ import LZString from "lz-string"; import BaseUIElement from "./UI/BaseUIElement"; import Table from "./UI/Base/Table"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; +import {Changes} from "./Logic/Osm/Changes"; +import {ElementStorage} from "./Logic/ElementStorage"; -const connection = new OsmConnection(false, false, new UIEventSource(undefined), ""); +const connection = new OsmConnection({ + osmConfiguration: 'osm', + changes: new Changes(), + layoutName: '', + allElements: new ElementStorage() +}); + let rendered = false; @@ -20,6 +28,7 @@ function salvageThemes(preferences: any) { const knownThemeNames = new Set(); const correctThemeNames = [] for (const key in preferences) { + try{ if (!(typeof key === "string")) { continue; } @@ -36,7 +45,7 @@ function salvageThemes(preferences: any) { } else { knownThemeNames.add(theme); } - } + }catch(e){console.error(e)}} for (const correctThemeName of correctThemeNames) { knownThemeNames.delete(correctThemeName); @@ -65,8 +74,13 @@ function salvageThemes(preferences: any) { try { jsonObject = JSON.parse(atob(combined)); } catch (e) { + try{ + // We try to decode with lz-string jsonObject = JSON.parse(Utils.UnMinify(LZString.decompressFromBase64(combined))) as LayoutConfigJson; + }catch(e0){ + console.log("Could not salvage theme. Initial parsing failed due to:", e,"\nWith LZ failed due ", e0) + } } diff --git a/scripts/ScriptUtils.ts b/scripts/ScriptUtils.ts index 3551ba5f8..22cdd0d93 100644 --- a/scripts/ScriptUtils.ts +++ b/scripts/ScriptUtils.ts @@ -48,13 +48,10 @@ export default class ScriptUtils { }) } - public static DownloadJSON(url, options?: { - headers: any - }): Promise { + public static DownloadJSON(url, headers?: any): Promise { return new Promise((resolve, reject) => { try { - - const headers = options?.headers ?? {} + headers = headers ?? {} headers.accept = "application/json" console.log("Fetching", url) const urlObj = new URL(url) diff --git a/scripts/generateCache.ts b/scripts/generateCache.ts index 5a8377125..a5a915bde 100644 --- a/scripts/generateCache.ts +++ b/scripts/generateCache.ts @@ -14,7 +14,7 @@ import RelationsTracker from "../Logic/Osm/RelationsTracker"; import * as OsmToGeoJson from "osmtogeojson"; import MetaTagging from "../Logic/MetaTagging"; import {UIEventSource} from "../Logic/UIEventSource"; -import {TileRange} from "../Models/TileRange"; +import {TileRange, Tiles} from "../Models/TileRange"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import ScriptUtils from "./ScriptUtils"; import PerLayerFeatureSourceSplitter from "../Logic/FeatureSource/PerLayerFeatureSourceSplitter"; @@ -86,7 +86,7 @@ async function downloadRaw(targetdir: string, r: TileRange, overpass: Overpass)/ } console.log("x:", (x - r.xstart), "/", (r.xend - r.xstart), "; y:", (y - r.ystart), "/", (r.yend - r.ystart), "; total: ", downloaded, "/", r.total, "failed: ", failed, "skipped: ", skipped) - const boundsArr = Utils.tile_bounds(r.zoomlevel, x, y) + const boundsArr = Tiles.tile_bounds(r.zoomlevel, x, y) const bounds = { north: Math.max(boundsArr[0][0], boundsArr[1][0]), south: Math.min(boundsArr[0][0], boundsArr[1][0]), @@ -174,7 +174,7 @@ function loadAllTiles(targetdir: string, r: TileRange, theme: LayoutConfig, extr allFeatures.push(...geojson.features) } } - return new StaticFeatureSource(allFeatures) + return new StaticFeatureSource(allFeatures, false) } /** @@ -225,7 +225,7 @@ function postProcess(allFeatures: FeatureSource, theme: LayoutConfig, relationsT delete feature.feature["bbox"] } // Lets save this tile! - const [z, x, y] = Utils.tile_from_index(tile.tileIndex) + const [z, x, y] = Tiles.tile_from_index(tile.tileIndex) console.log("Writing tile ", z, x, y, layerId) const targetPath = geoJsonName(targetdir + "_" + layerId, x, y, z) createdTiles.push(tile.tileIndex) @@ -241,7 +241,7 @@ function postProcess(allFeatures: FeatureSource, theme: LayoutConfig, relationsT // Only thing left to do is to create the index const path = targetdir + "_" + layerId + "_overview.json" const perX = {} - createdTiles.map(i => Utils.tile_from_index(i)).forEach(([z, x, y]) => { + createdTiles.map(i => Tiles.tile_from_index(i)).forEach(([z, x, y]) => { const key = "" + x if (perX[key] === undefined) { perX[key] = [] @@ -279,7 +279,7 @@ async function main(args: string[]) { const lat1 = Number(args[5]) const lon1 = Number(args[6]) - const tileRange = Utils.TileRangeBetween(zoomlevel, lat0, lon0, lat1, lon1) + const tileRange = Tiles.TileRangeBetween(zoomlevel, lat0, lon0, lat1, lon1) const theme = AllKnownLayouts.allKnownLayouts.get(themeName) if (theme === undefined) { diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 2bdc852c9..d6d8c11d2 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -33,7 +33,7 @@ class TranslationPart { } const v = translations[translationsKey] if (typeof (v) != "string") { - console.error("Non-string object in translation: ", translations[translationsKey]) + console.error("Non-string object in translation while trying to add more translations to '", translationsKey ,"': ", v) throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation" } this.contents.set(translationsKey, v) @@ -41,25 +41,39 @@ class TranslationPart { } recursiveAdd(object: any, context: string) { - - - const isProbablyTranslationObject = knownLanguages.map(l => object.hasOwnProperty(l)).filter(x => x).length > 0; + const isProbablyTranslationObject = knownLanguages.some(l => object.hasOwnProperty(l)); if (isProbablyTranslationObject) { this.addTranslationObject(object, context) return; } - for (const key in object) { + for (let key in object) { if (!object.hasOwnProperty(key)) { continue; } const v = object[key] + if (v == null) { console.warn("Got a null value for key ", key) continue } + if (v["id"] !== undefined && context.endsWith("tagRenderings")) { + // We use the embedded id as key instead of the index as this is more stable + // Note: indonesian is shortened as 'id' as well! + if (v["en"] !== undefined || v["nl"] !== undefined) { + // This is probably a translation already! + // pass + } else { + + key = v["id"] + if (typeof key !== "string") { + throw "Panic: found a non-string ID at" + context + } + } + } + if (typeof v !== "object") { continue; } @@ -120,7 +134,10 @@ class TranslationPart { } } - +/** + * Checks that the given object only contains string-values + * @param tr + */ function isTranslation(tr: any): boolean { for (const key in tr) { if (typeof tr[key] !== "string") { @@ -130,6 +147,11 @@ function isTranslation(tr: any): boolean { return true; } +/** + * Converts a translation object into something that can be added to the 'generated translations' + * @param obj + * @param depth + */ function transformTranslation(obj: any, depth = 1) { if (isTranslation(obj)) { @@ -150,6 +172,9 @@ function transformTranslation(obj: any, depth = 1) { } +/** + * Generates the big compiledTranslations file + */ function genTranslations() { const translations = JSON.parse(fs.readFileSync("./assets/generated/translations.json", "utf-8")) const transformed = transformTranslation(translations); @@ -163,7 +188,10 @@ function genTranslations() { } -// Read 'lang/*.json', writes to 'assets/generated/translations.json' +/** + * Reads 'lang/*.json', writes them into to 'assets/generated/translations.json'. + * This is only for the core translations + */ function compileTranslationsFromWeblate() { const translations = ScriptUtils.readDirRecSync("./langs", 1) .filter(path => path.indexOf(".json") > 0) @@ -181,7 +209,11 @@ function compileTranslationsFromWeblate() { } -// Get all the strings out of the layers; writes them onto the weblate paths +/** + * Get all the strings out of the layers; writes them onto the weblate paths + * @param objects + * @param target + */ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: string } }[], target: string) { const tr = new TranslationPart(); @@ -203,6 +235,7 @@ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: s } let json = tr.toJson(lang) try { + json = JSON.stringify(JSON.parse(json), null, " "); } catch (e) { console.error(e) @@ -212,15 +245,34 @@ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: s } } +/** + * Merge two objects together + * @param source: where the tranlations come from + * @param target: the object in which the translations should be merged + * @param language: the language code + * @param context: context for error handling + * @constructor + */ function MergeTranslation(source: any, target: any, language: string, context: string = "") { + let keyRemapping: Map = undefined + if (context.endsWith(".tagRenderings")) { + keyRemapping = new Map() + for (const key in target) { + keyRemapping.set(target[key].id, key) + } + } + for (const key in source) { if (!source.hasOwnProperty(key)) { continue } + const sourceV = source[key]; - const targetV = target[key] + const targetV = target[keyRemapping?.get(key) ?? key] + if (typeof sourceV === "string") { + // Add the translation if (targetV === undefined) { if (typeof target === "string") { throw "Trying to merge a translation into a fixed string at " + context + " for key " + key; @@ -281,9 +333,9 @@ function loadTranslationFilesFrom(target: string): Map { for (const translationFilePath of translationFilePaths) { let language = translationFilePath.substr(translationFilePath.lastIndexOf("/") + 1) language = language.substr(0, language.length - 5) - try{ + try { translationFiles.set(language, JSON.parse(readFileSync(translationFilePath, "utf8"))) - }catch(e){ + } catch (e) { console.error("Invalid JSON file or file does not exist", translationFilePath) throw e; } @@ -299,10 +351,13 @@ function mergeLayerTranslations() { const layerFiles = ScriptUtils.getLayerFiles(); for (const layerFile of layerFiles) { mergeLayerTranslation(layerFile.parsed, layerFile.path, loadTranslationFilesFrom("layers")) - writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) + writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) } } +/** + * Load the translations into the theme files + */ function mergeThemeTranslations() { const themeFiles = ScriptUtils.getThemeFiles(); for (const themeFile of themeFiles) { diff --git a/scripts/generateWikiPage.ts b/scripts/generateWikiPage.ts index ca03e3fb5..688dfd2fe 100644 --- a/scripts/generateWikiPage.ts +++ b/scripts/generateWikiPage.ts @@ -20,8 +20,8 @@ function generateWikiEntry(layout: LayoutConfig) { |name= [https://mapcomplete.osm.be/${layout.id} ${layout.id}] |region= Worldwide |lang= ${languages} -|descr= A MapComplete theme: ${Translations.W(layout.description) - .InnerRenderAsString() +|descr= A MapComplete theme: ${Translations.WT(layout.description) + .textFor("en") .replace(".*<\/a>/, "]]") } diff --git a/scripts/lint.ts b/scripts/lint.ts new file mode 100644 index 000000000..a4f3902a6 --- /dev/null +++ b/scripts/lint.ts @@ -0,0 +1,51 @@ + +/* + * This script reads all theme and layer files and reformats them inplace + * Use with caution, make a commit beforehand! + */ + + +import ScriptUtils from "./ScriptUtils"; +import {readFileSync, writeFileSync} from "fs"; +import {tag} from "@turf/turf"; +import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; + +/** + * In place fix + */ +function fixLayerConfig(config: LayerConfigJson) : void{ + if(config.tagRenderings === undefined){ + return + } + + for (const tagRendering of config.tagRenderings) { + if(tagRendering["#"] !== undefined){ + tagRendering["id"] = tagRendering["#"] + delete tagRendering["#"] + } + if(tagRendering["id"] === undefined){ + if(tagRendering["freeform"]?.key !== undefined ) { + tagRendering["id"] = config.id+"-"+tagRendering["freeform"]["key"] + } + } + } +} + +const layerFiles = ScriptUtils.getLayerFiles(); +for (const layerFile of layerFiles) { + fixLayerConfig(layerFile.parsed) + writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) +} + +const themeFiles = ScriptUtils.getThemeFiles() +for (const themeFile of themeFiles) { + for (const layerConfig of themeFile.parsed.layers ?? []) { + if(typeof layerConfig === "string" || layerConfig["builtin"]!== undefined){ + continue + } + // @ts-ignore + fixLayerConfig(layerConfig) + } + writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) +} +//*/ \ No newline at end of file diff --git a/test.ts b/test.ts index 86a1c8f6e..7dd34cd93 100644 --- a/test.ts +++ b/test.ts @@ -1,50 +1,50 @@ -import SplitRoadWizard from "./UI/Popup/SplitRoadWizard"; -import State from "./State"; +<<<<<<< HEAD +import {Tiles} from "./Models/TileRange"; +import OsmFeatureSource from "./Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource"; +import {Utils} from "./Utils"; import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; -import MinimapImplementation from "./UI/Base/MinimapImplementation"; -import {UIEventSource} from "./Logic/UIEventSource"; -import FilteredLayer from "./Models/FilteredLayer"; -import {And} from "./Logic/Tags/And"; +import LayerConfig from "./Models/ThemeConfig/LayerConfig"; -const layout = AllKnownLayouts.allKnownLayouts.get("cyclestreets") -State.state = new State(layout) -MinimapImplementation.initialize() -const feature = { - "type": "Feature", - "properties": { - id: "way/1234", - "highway":"residential", - "cyclestreet":"yes" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 3.2207107543945312, - 51.21978729870313 - ], - [ - 3.2198524475097656, - 51.21899435057332 - ], - [ - 3.2155394554138184, - 51.21617188199714 - ] - ] +const allLayers: LayerConfig[] = [] +const seenIds = new Set() +for (const layoutConfig of AllKnownLayouts.layoutsList) { + if (layoutConfig.hideFromOverview) { + continue + } + for (const layer of layoutConfig.layers) { + if (seenIds.has(layer.id)) { + continue + } + seenIds.add(layer.id) + allLayers.push(layer) } } -State.state.allElements.addOrGetElement(feature) -State.state.filteredLayers = new UIEventSource( - layout.layers.map( l => ({ - layerDef :l, - appliedFilters: new UIEventSource(undefined), - isDisplayed: new UIEventSource(undefined) - })) -) +console.log("All layer ids", allLayers.map(l => l.id)) -const splitroad = new SplitRoadWizard("way/1234") - splitroad.AttachTo("maindiv") +const src = new OsmFeatureSource({ + backend: "https://www.openstreetmap.org", + handleTile: tile => console.log("Got tile", tile), + allLayers: allLayers +}) +src.LoadTile(16, 33354, 21875).then(geojson => { + console.log("Got geojson", geojson); + Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), "test.geojson", { + mimetype: "application/vnd.geo+json" + }) +}) +//*/ +======= +import LocationInput from "./UI/Input/LocationInput"; +import Loc from "./Models/Loc"; +import {UIEventSource} from "./Logic/UIEventSource"; -splitroad.dialogIsOpened.setData(true) +new LocationInput({ + centerLocation: new UIEventSource({ + lat: 51.1110, + lon: 3.3701, + zoom : 14 + }) +}).SetStyle("height: 500px") + .AttachTo("maindiv"); +>>>>>>> feature/animated-precise-input diff --git a/test/GeoOperations.spec.ts b/test/GeoOperations.spec.ts index 7a556b20d..56e07acaf 100644 --- a/test/GeoOperations.spec.ts +++ b/test/GeoOperations.spec.ts @@ -2,6 +2,8 @@ import {Utils} from "../Utils"; import * as Assert from "assert"; import T from "./TestHelper"; import {GeoOperations} from "../Logic/GeoOperations"; +import {equal} from "assert"; +import {BBox} from "../Logic/BBox"; Utils.runningFromConsole = true; @@ -176,7 +178,16 @@ export default class GeoOperationsSpec extends T { const overlap = GeoOperations.calculateOverlap(point, [GeoOperationsSpec.polygon]); Assert.equal(1, overlap.length) - }] + }], + ["bbox bounds test", + () => { + const bbox = BBox.fromTile(16, 32754, 21785) + equal(-0.076904296875, bbox.minLon) + equal(-0.0714111328125, bbox.maxLon) + equal(51.5292513551899, bbox.minLat) + equal(51.53266860674158, bbox.maxLat) + } + ] ] ) diff --git a/test/ImageSearcher.spec.ts b/test/ImageSearcher.spec.ts deleted file mode 100644 index 9b3d713ac..000000000 --- a/test/ImageSearcher.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Utils} from "../Utils"; -import {equal} from "assert"; -import T from "./TestHelper"; -import {UIEventSource} from "../Logic/UIEventSource"; -import {ImageSearcher} from "../Logic/Actors/ImageSearcher"; - -Utils.runningFromConsole = true; -export default class ImageSearcherSpec extends T { - - constructor() { - super("imagesearcher", [ - [ - "Should find images", - () => { - const tags = new UIEventSource({ - "mapillary": "https://www.mapillary.com/app/?pKey=bYH6FFl8LXAPapz4PNSh3Q" - }); - const searcher = ImageSearcher.construct(tags) - const result = searcher.data[0]; - equal(result.url, "https://www.mapillary.com/map/im/bYH6FFl8LXAPapz4PNSh3Q"); - } - ], - ]); - - } - - -} diff --git a/test/OsmConnection.spec.ts b/test/OsmConnection.spec.ts index 0b6cf3b47..9d7b114f5 100644 --- a/test/OsmConnection.spec.ts +++ b/test/OsmConnection.spec.ts @@ -2,6 +2,9 @@ import T from "./TestHelper"; import UserDetails, {OsmConnection} from "../Logic/Osm/OsmConnection"; import {UIEventSource} from "../Logic/UIEventSource"; import ScriptUtils from "../scripts/ScriptUtils"; +import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; +import {ElementStorage} from "../Logic/ElementStorage"; +import {Changes} from "../Logic/Osm/Changes"; export default class OsmConnectionSpec extends T { @@ -15,12 +18,14 @@ export default class OsmConnectionSpec extends T { super("osmconnection", [ ["login on dev", () => { - const osmConn = new OsmConnection(false, false, - new UIEventSource(undefined), - "Unit test", - true, - "osm-test" - ) + const osmConn = new OsmConnection({ + osmConfiguration: "osm-test", + layoutName: "Unit test", + allElements: new ElementStorage(), + changes: new Changes(), + oauth_token: new UIEventSource(OsmConnectionSpec._osm_token) + } + ); osmConn.userDetails.map((userdetails: UserDetails) => { if (userdetails.loggedIn) { diff --git a/test/TestAll.ts b/test/TestAll.ts index 1a25a0afc..6123681fb 100644 --- a/test/TestAll.ts +++ b/test/TestAll.ts @@ -1,7 +1,6 @@ import TagSpec from "./Tag.spec"; import ImageAttributionSpec from "./ImageAttribution.spec"; import GeoOperationsSpec from "./GeoOperations.spec"; -import ImageSearcherSpec from "./ImageSearcher.spec"; import ThemeSpec from "./Theme.spec"; import UtilsSpec from "./Utils.spec"; import OsmObjectSpec from "./OsmObject.spec"; @@ -10,6 +9,7 @@ import UnitsSpec from "./Units.spec"; import RelationSplitHandlerSpec from "./RelationSplitHandler.spec"; import SplitActionSpec from "./SplitAction.spec"; import {Utils} from "../Utils"; +import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec"; ScriptUtils.fixUtils() @@ -18,12 +18,12 @@ const allTests = [ new TagSpec(), new ImageAttributionSpec(), new GeoOperationsSpec(), - new ImageSearcherSpec(), new ThemeSpec(), new UtilsSpec(), new UnitsSpec(), new RelationSplitHandlerSpec(), - new SplitActionSpec() + new SplitActionSpec(), + new TileFreshnessCalculatorSpec() ] Utils.externalDownloadFunction = async (url) => { diff --git a/test/TileFreshnessCalculator.spec.ts b/test/TileFreshnessCalculator.spec.ts new file mode 100644 index 000000000..6305b9a5d --- /dev/null +++ b/test/TileFreshnessCalculator.spec.ts @@ -0,0 +1,31 @@ +import T from "./TestHelper"; +import TileFreshnessCalculator from "../Logic/FeatureSource/TileFreshnessCalculator"; +import {Tiles} from "../Models/TileRange"; +import {equal} from "assert"; + +export default class TileFreshnessCalculatorSpec extends T { + + constructor() { + super("TileFreshnessCalculatorSpec", [ + [ + "TileFresnessTests", + () => { + const calc = new TileFreshnessCalculator(); + // 19/266407/175535 + const date = new Date() + date.setTime(42) + calc.addTileLoad(Tiles.tile_index(19, 266406, 175534), date) + equal(42, calc.freshnessFor(19, 266406, 175534).getTime()) + equal(42, calc.freshnessFor(20, 266406 * 2, 175534 * 2 + 1).getTime()) + equal(undefined, calc.freshnessFor(19, 266406, 175535)) + equal(undefined, calc.freshnessFor(18, 266406 / 2, 175534 / 2)) + calc.addTileLoad(Tiles.tile_index(19, 266406, 175534+1), date) + calc.addTileLoad(Tiles.tile_index(19, 266406+1, 175534), date) + calc.addTileLoad(Tiles.tile_index(19, 266406+1, 175534+1), date) + equal(42, calc.freshnessFor(18, 266406 / 2, 175534 / 2).getTime()) + } + ] + ]) + } + +} \ No newline at end of file