Merge branch 'develop' into feature/bicycle_road
BIN
Docs/Misc/Climbing.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
Docs/Misc/Kakampink.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
Docs/Misc/StatisticsOnwheels.png
Normal file
After Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 274 KiB |
BIN
Docs/Misc/shop_selection.gif
Normal file
After Width: | Height: | Size: 300 KiB |
53
Docs/Presentations/SOTM2022-workshop.abstract.txt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# What do I want to tell at SOTM '22?
|
||||||
|
|
||||||
|
4 main topics:
|
||||||
|
|
||||||
|
The MapComplete Editor:
|
||||||
|
|
||||||
|
- What is MapComplete? The vision
|
||||||
|
+ Simple to use viewer
|
||||||
|
+ Simple to contribute
|
||||||
|
+ Packed with features under the hood (where applicable)
|
||||||
|
+ Pareto frontier
|
||||||
|
|
||||||
|
- What is a theme?
|
||||||
|
+ One or more layers + introduction text + some meta (such as icon)
|
||||||
|
+ Vision on what the target group is (who will use it? For what purpose?)
|
||||||
|
+ Written in a .json-file
|
||||||
|
|
||||||
|
- What is a .json-file
|
||||||
|
+ A flat text-file (create a .txt)
|
||||||
|
|
||||||
|
- What is a layer?
|
||||||
|
+ One logical type of feature
|
||||||
|
- Specifiy the tags that are needed to match
|
||||||
|
- Uses OSM as default datasource, but an online (sliced) geojson is an option too, e.g. to show/import
|
||||||
|
+ Specifies the elements to show in the popup
|
||||||
|
+ Specifies how it is rendered
|
||||||
|
+ Specifies if new elements can be added and with which tags
|
||||||
|
-> Don't mix, e.g. don't mix post-boxes with post offices
|
||||||
|
-> Don't use an adverb, e.g. "all shops ~~which accept cash~~". What if the shop is already there but the payment methods are not known yet? (use a filter instead)
|
||||||
|
|
||||||
|
- What is a TagRendering?
|
||||||
|
+ Converts the objects attributes into a text on the screen
|
||||||
|
+ If a question is added, it'll ask the user the right answer
|
||||||
|
-> Do use full sentences
|
||||||
|
-> Start with the step 'attributes to text', then add the question
|
||||||
|
-> Don't write "yes, this POI has ..." or even worse "yes"/"no"
|
||||||
|
|
||||||
|
- Deploying
|
||||||
|
+ copy paste into a base64-decoder
|
||||||
|
+ Go to "mapcomplete.osm.be/index?userlayout=true#<paste your encoded file here>"
|
||||||
|
+ Oh Noes! An error msg!
|
||||||
|
|
||||||
|
- sharing
|
||||||
|
+ Share often and early. I'd rather have a half-finished theme via chat/wiki that can be improved upon then no theme at all
|
||||||
|
+ When done: make a pull request via github (you'll get translations, documentation, integration with taginfo and a chatbot for free)
|
||||||
|
|
||||||
|
- A dash of Magic
|
||||||
|
+ Calculated tags
|
||||||
|
+ Twin layers (fritures)
|
||||||
|
+ Imports
|
||||||
|
|
||||||
|
- Future work:
|
||||||
|
+ Improve this flow
|
BIN
Docs/Presentations/WikidataAndMapComplete.mp4
Normal file
|
@ -235,7 +235,7 @@ export default class SimpleMetaTaggers {
|
||||||
|
|
||||||
private static canonicalize = new SimpleMetaTagger(
|
private static canonicalize = new SimpleMetaTagger(
|
||||||
{
|
{
|
||||||
doc: "If 'units' is defined in the layoutConfig, then this metatagger will rewrite the specified keys to have the canonical form (e.g. `1meter` will be rewritten to `1m`)",
|
doc: "If 'units' is defined in the layoutConfig, then this metatagger will rewrite the specified keys to have the canonical form (e.g. `1meter` will be rewritten to `1m`; `1` will be rewritten to `1m` as well)",
|
||||||
keys: ["Theme-defined keys"],
|
keys: ["Theme-defined keys"],
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -261,13 +261,14 @@ export default class SimpleMetaTaggers {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const value = feature.properties[key]
|
const value = feature.properties[key]
|
||||||
const denom = unit.findDenomination(value)
|
const denom = unit.findDenomination(value, () => feature.properties["_country"])
|
||||||
if (denom === undefined) {
|
if (denom === undefined) {
|
||||||
// no valid value found
|
// no valid value found
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const [, denomination] = denom;
|
const [, denomination] = denom;
|
||||||
let canonical = denomination?.canonicalValue(value) ?? undefined;
|
const defaultDenom = unit.getDefaultDenomination(() => feature.properties["_country"])
|
||||||
|
let canonical = denomination?.canonicalValue(value, defaultDenom == denomination) ?? undefined;
|
||||||
if (canonical === value) {
|
if (canonical === value) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import {Translation} from "../UI/i18n/Translation";
|
import {Translation} from "../UI/i18n/Translation";
|
||||||
import {ApplicableUnitJson} from "./ThemeConfig/Json/UnitConfigJson";
|
import {DenominationConfigJson} from "./ThemeConfig/Json/UnitConfigJson";
|
||||||
import Translations from "../UI/i18n/Translations";
|
import Translations from "../UI/i18n/Translations";
|
||||||
import {Store, UIEventSource} from "../Logic/UIEventSource";
|
import {Store} from "../Logic/UIEventSource";
|
||||||
import BaseUIElement from "../UI/BaseUIElement";
|
import BaseUIElement from "../UI/BaseUIElement";
|
||||||
import Toggle from "../UI/Input/Toggle";
|
import Toggle from "../UI/Input/Toggle";
|
||||||
|
|
||||||
export class Denomination {
|
export class Denomination {
|
||||||
public readonly canonical: string;
|
public readonly canonical: string;
|
||||||
public readonly _canonicalSingular: string;
|
public readonly _canonicalSingular: string;
|
||||||
public readonly default: boolean;
|
public readonly useAsDefaultInput: boolean | string[]
|
||||||
|
public readonly useIfNoUnitGiven : boolean | string[]
|
||||||
public readonly prefix: boolean;
|
public readonly prefix: boolean;
|
||||||
public readonly alternativeDenominations: string [];
|
public readonly alternativeDenominations: string [];
|
||||||
private readonly _human: Translation;
|
private readonly _human: Translation;
|
||||||
private readonly _humanSingular?: Translation;
|
private readonly _humanSingular?: Translation;
|
||||||
|
|
||||||
|
|
||||||
constructor(json: ApplicableUnitJson, context: string) {
|
constructor(json: DenominationConfigJson, context: string) {
|
||||||
context = `${context}.unit(${json.canonicalDenomination})`
|
context = `${context}.unit(${json.canonicalDenomination})`
|
||||||
this.canonical = json.canonicalDenomination.trim()
|
this.canonical = json.canonicalDenomination.trim()
|
||||||
if (this.canonical === undefined) {
|
if (this.canonical === undefined) {
|
||||||
|
@ -32,7 +33,11 @@ export class Denomination {
|
||||||
|
|
||||||
this.alternativeDenominations = json.alternativeDenomination?.map(v => v.trim()) ?? []
|
this.alternativeDenominations = json.alternativeDenomination?.map(v => v.trim()) ?? []
|
||||||
|
|
||||||
this.default = json.default ?? false;
|
if(json["default"] !== undefined) {
|
||||||
|
throw `${context} uses the old 'default'-key. Use "useIfNoUnitGiven" or "useAsDefaultInput" instead`
|
||||||
|
}
|
||||||
|
this.useIfNoUnitGiven = json.useIfNoUnitGiven
|
||||||
|
this.useAsDefaultInput = json.useAsDefaultInput ?? json.useIfNoUnitGiven
|
||||||
|
|
||||||
this._human = Translations.T(json.human, context + "human")
|
this._human = Translations.T(json.human, context + "human")
|
||||||
this._humanSingular = Translations.T(json.humanSingular, context + "humanSingular")
|
this._humanSingular = Translations.T(json.humanSingular, context + "humanSingular")
|
||||||
|
@ -68,32 +73,31 @@ export class Denomination {
|
||||||
* const unit = new Denomination({
|
* const unit = new Denomination({
|
||||||
* canonicalDenomination: "m",
|
* canonicalDenomination: "m",
|
||||||
* alternativeDenomination: ["meter"],
|
* alternativeDenomination: ["meter"],
|
||||||
* 'default': true,
|
|
||||||
* human: {
|
* human: {
|
||||||
* en: "meter"
|
* en: "meter"
|
||||||
* }
|
* }
|
||||||
* }, "test")
|
* }, "test")
|
||||||
* unit.canonicalValue("42m") // =>"42 m"
|
* unit.canonicalValue("42m", true) // =>"42 m"
|
||||||
* unit.canonicalValue("42") // =>"42 m"
|
* unit.canonicalValue("42", true) // =>"42 m"
|
||||||
* unit.canonicalValue("42 m") // =>"42 m"
|
* unit.canonicalValue("42 m", true) // =>"42 m"
|
||||||
* unit.canonicalValue("42 meter") // =>"42 m"
|
* unit.canonicalValue("42 meter", true) // =>"42 m"
|
||||||
*
|
* unit.canonicalValue("42m", true) // =>"42 m"
|
||||||
|
* unit.canonicalValue("42", true) // =>"42 m"
|
||||||
*
|
*
|
||||||
* // Should be trimmed if canonical is empty
|
* // Should be trimmed if canonical is empty
|
||||||
* const unit = new Denomination({
|
* const unit = new Denomination({
|
||||||
* canonicalDenomination: "",
|
* canonicalDenomination: "",
|
||||||
* alternativeDenomination: ["meter","m"],
|
* alternativeDenomination: ["meter","m"],
|
||||||
* 'default': true,
|
|
||||||
* human: {
|
* human: {
|
||||||
* en: "meter"
|
* en: "meter"
|
||||||
* }
|
* }
|
||||||
* }, "test")
|
* }, "test")
|
||||||
* unit.canonicalValue("42m") // =>"42"
|
* unit.canonicalValue("42m", true) // =>"42"
|
||||||
* unit.canonicalValue("42") // =>"42"
|
* unit.canonicalValue("42", true) // =>"42"
|
||||||
* unit.canonicalValue("42 m") // =>"42"
|
* unit.canonicalValue("42 m", true) // =>"42"
|
||||||
* unit.canonicalValue("42 meter") // =>"42"
|
* unit.canonicalValue("42 meter", true) // =>"42"
|
||||||
*/
|
*/
|
||||||
public canonicalValue(value: string, actAsDefault?: boolean) : string {
|
public canonicalValue(value: string, actAsDefault: boolean) : string {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +118,7 @@ export class Denomination {
|
||||||
*
|
*
|
||||||
* Returns null if it doesn't match this unit
|
* Returns null if it doesn't match this unit
|
||||||
*/
|
*/
|
||||||
public StrippedValue(value: string, actAsDefault?: boolean): string {
|
public StrippedValue(value: string, actAsDefault: boolean): string {
|
||||||
|
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -153,15 +157,26 @@ export class Denomination {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.default || actAsDefault) {
|
if (!actAsDefault) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const parsed = Number(value.trim())
|
const parsed = Number(value.trim())
|
||||||
if (!isNaN(parsed)) {
|
if (!isNaN(parsed)) {
|
||||||
return value.trim();
|
return value.trim();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isDefaultUnit(country: () => string) {
|
||||||
|
if(this.useIfNoUnitGiven === true){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if(this.useIfNoUnitGiven === false){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.useIfNoUnitGiven.indexOf(country()) >= 0
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,11 +13,16 @@ import {AddContextToTranslations} from "./AddContextToTranslations";
|
||||||
class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | { builtin: string | string[], override: any }, TagRenderingConfigJson[]> {
|
class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | { builtin: string | string[], override: any }, TagRenderingConfigJson[]> {
|
||||||
private readonly _state: DesugaringContext;
|
private readonly _state: DesugaringContext;
|
||||||
private readonly _self: LayerConfigJson;
|
private readonly _self: LayerConfigJson;
|
||||||
|
private readonly _options: {
|
||||||
|
/* If true, will copy the 'osmSource'-tags into the condition */
|
||||||
|
applyCondition?: true | boolean;
|
||||||
|
};
|
||||||
|
|
||||||
constructor(state: DesugaringContext, self: LayerConfigJson) {
|
constructor(state: DesugaringContext, self: LayerConfigJson, options?: { applyCondition?: true | boolean;}) {
|
||||||
super("Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question", [], "ExpandTagRendering");
|
super("Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question", [], "ExpandTagRendering");
|
||||||
this._state = state;
|
this._state = state;
|
||||||
this._self = self;
|
this._self = self;
|
||||||
|
this._options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
convert(json: string | TagRenderingConfigJson | { builtin: string | string[]; override: any }, context: string): { result: TagRenderingConfigJson[]; errors: string[]; warnings: string[] } {
|
convert(json: string | TagRenderingConfigJson | { builtin: string | string[]; override: any }, context: string): { result: TagRenderingConfigJson[]; errors: string[]; warnings: string[] } {
|
||||||
|
@ -65,13 +70,15 @@ class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | {
|
||||||
|
|
||||||
const contextWriter = new AddContextToTranslations<TagRenderingConfigJson>("layers:")
|
const contextWriter = new AddContextToTranslations<TagRenderingConfigJson>("layers:")
|
||||||
for (let i = 0; i < matchingTrs.length; i++) {
|
for (let i = 0; i < matchingTrs.length; i++) {
|
||||||
// The matched tagRenderings are 'stolen' from another layer. This means that they must match the layer condition before being shown
|
|
||||||
let found: TagRenderingConfigJson = Utils.Clone(matchingTrs[i]);
|
let found: TagRenderingConfigJson = Utils.Clone(matchingTrs[i]);
|
||||||
|
if(this._options?.applyCondition){
|
||||||
|
// The matched tagRenderings are 'stolen' from another layer. This means that they must match the layer condition before being shown
|
||||||
if (found.condition === undefined) {
|
if (found.condition === undefined) {
|
||||||
found.condition = layer.source.osmTags
|
found.condition = layer.source.osmTags
|
||||||
} else {
|
} else {
|
||||||
found.condition = {and: [found.condition, layer.source.osmTags]}
|
found.condition = {and: [found.condition, layer.source.osmTags]}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
found = contextWriter.convertStrict(found, layer.id + ".tagRenderings." + found["id"])
|
found = contextWriter.convertStrict(found, layer.id + ".tagRenderings." + found["id"])
|
||||||
matchingTrs[i] = found
|
matchingTrs[i] = found
|
||||||
|
@ -561,7 +568,7 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||||
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
||||||
new On("tagRenderings", layer => new Concat(new ExpandTagRendering(state, layer))),
|
new On("tagRenderings", layer => new Concat(new ExpandTagRendering(state, layer))),
|
||||||
new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
||||||
new On("mapRendering", layer => new Each(new On("icon", new FirstOf(new ExpandTagRendering(state, layer))))),
|
new On("mapRendering", layer => new Each(new On("icon", new FirstOf(new ExpandTagRendering(state, layer, {applyCondition: false}))))),
|
||||||
new SetDefault("titleIcons", ["defaults"]),
|
new SetDefault("titleIcons", ["defaults"]),
|
||||||
new On("titleIcons", layer => new Concat(new ExpandTagRendering(state, layer)))
|
new On("titleIcons", layer => new Concat(new ExpandTagRendering(state, layer)))
|
||||||
);
|
);
|
||||||
|
|
|
@ -613,6 +613,13 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
|
||||||
information.push(...(r.information ?? []))
|
information.push(...(r.information ?? []))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const hasCondition = json.mapRendering?.filter(mr => mr["icon"] !== undefined && mr["icon"]["condition"] !== undefined)
|
||||||
|
if(hasCondition?.length > 0){
|
||||||
|
errors.push("At "+context+":\n One or more icons in the mapRenderings have a condition set. Don't do this, as this will result in an invisible but clickable element. Use extra filters in the source instead. The offending mapRenderings are:\n"+JSON.stringify(hasCondition, null, " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (json.presets !== undefined) {
|
if (json.presets !== undefined) {
|
||||||
|
|
||||||
// Check that a preset will be picked up by the layer itself
|
// Check that a preset will be picked up by the layer itself
|
||||||
|
|
|
@ -14,13 +14,32 @@ export default interface UnitConfigJson {
|
||||||
/**
|
/**
|
||||||
* The possible denominations
|
* The possible denominations
|
||||||
*/
|
*/
|
||||||
applicableUnits: ApplicableUnitJson[]
|
applicableUnits: DenominationConfigJson[]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplicableUnitJson {
|
export interface DenominationConfigJson {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The canonical value which will be added to the value in OSM.
|
* If this evaluates to true and the value to interpret has _no_ unit given, assumes that this unit is meant.
|
||||||
|
* Alternatively, a list of country codes can be given where this acts as the default interpretation
|
||||||
|
*
|
||||||
|
* E.g., a denomination using "meter" would probably set this flag to "true";
|
||||||
|
* a denomination for "mp/h" will use the condition "_country=gb" to indicate that it is the default in the UK.
|
||||||
|
*
|
||||||
|
* If none of the units indicate that they are the default, the first denomination will be used instead
|
||||||
|
*/
|
||||||
|
useIfNoUnitGiven?: boolean | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this value as default denomination when the user inputs a value (e.g. to force using 'centimeters' instead of 'meters' by default).
|
||||||
|
* If unset for all values, this will use 'useIfNoUnitGiven'. If at least one denomination has this set, this will default to false
|
||||||
|
*/
|
||||||
|
useAsDefaultInput?: boolean | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The canonical value for this denomination which will be added to the value in OSM.
|
||||||
* e.g. "m" for meters
|
* e.g. "m" for meters
|
||||||
* If the user inputs '42', the canonical value will be added and it'll become '42m'.
|
* If the user inputs '42', the canonical value will be added and it'll become '42m'.
|
||||||
*
|
*
|
||||||
|
@ -28,8 +47,11 @@ export interface ApplicableUnitJson {
|
||||||
* In this case, an empty string should be used
|
* In this case, an empty string should be used
|
||||||
*/
|
*/
|
||||||
canonicalDenomination: string,
|
canonicalDenomination: string,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The canonical denomination in the case that the unit is precisely '1'
|
* The canonical denomination in the case that the unit is precisely '1'.
|
||||||
|
* Used for display purposes
|
||||||
*/
|
*/
|
||||||
canonicalDenominationSingular?: string,
|
canonicalDenominationSingular?: string,
|
||||||
|
|
||||||
|
@ -63,9 +85,5 @@ export interface ApplicableUnitJson {
|
||||||
*/
|
*/
|
||||||
prefix?: boolean
|
prefix?: boolean
|
||||||
|
|
||||||
/**
|
|
||||||
* The default interpretation - only one can be set.
|
|
||||||
* If none is set, the first unit will be considered the default interpretation of a value without a unit
|
|
||||||
*/
|
|
||||||
default?: boolean
|
|
||||||
}
|
}
|
|
@ -14,8 +14,6 @@ import List from "../../UI/Base/List";
|
||||||
import {MappingConfigJson, QuestionableTagRenderingConfigJson} from "./Json/QuestionableTagRenderingConfigJson";
|
import {MappingConfigJson, QuestionableTagRenderingConfigJson} from "./Json/QuestionableTagRenderingConfigJson";
|
||||||
import {FixedUiElement} from "../../UI/Base/FixedUiElement";
|
import {FixedUiElement} from "../../UI/Base/FixedUiElement";
|
||||||
import {Paragraph} from "../../UI/Base/Paragraph";
|
import {Paragraph} from "../../UI/Base/Paragraph";
|
||||||
import spec = Mocha.reporters.spec;
|
|
||||||
import SpecialVisualizations from "../../UI/SpecialVisualizations";
|
|
||||||
|
|
||||||
export interface Mapping {
|
export interface Mapping {
|
||||||
readonly if: TagsFilter,
|
readonly if: TagsFilter,
|
||||||
|
|
|
@ -8,14 +8,11 @@ export class Unit {
|
||||||
public readonly appliesToKeys: Set<string>;
|
public readonly appliesToKeys: Set<string>;
|
||||||
public readonly denominations: Denomination[];
|
public readonly denominations: Denomination[];
|
||||||
public readonly denominationsSorted: Denomination[];
|
public readonly denominationsSorted: Denomination[];
|
||||||
public readonly defaultDenom: Denomination;
|
|
||||||
public readonly eraseInvalid: boolean;
|
public readonly eraseInvalid: boolean;
|
||||||
private readonly possiblePostFixes: string[] = []
|
|
||||||
|
|
||||||
constructor(appliesToKeys: string[], applicableUnits: Denomination[], eraseInvalid: boolean) {
|
constructor(appliesToKeys: string[], applicableDenominations: Denomination[], eraseInvalid: boolean) {
|
||||||
this.appliesToKeys = new Set(appliesToKeys);
|
this.appliesToKeys = new Set(appliesToKeys);
|
||||||
this.denominations = applicableUnits;
|
this.denominations = applicableDenominations;
|
||||||
this.defaultDenom = applicableUnits.filter(denom => denom.default)[0]
|
|
||||||
this.eraseInvalid = eraseInvalid
|
this.eraseInvalid = eraseInvalid
|
||||||
|
|
||||||
const seenUnitExtensions = new Set<string>();
|
const seenUnitExtensions = new Set<string>();
|
||||||
|
@ -52,8 +49,6 @@ export class Unit {
|
||||||
addPostfixesOf(denomination._canonicalSingular)
|
addPostfixesOf(denomination._canonicalSingular)
|
||||||
denomination.alternativeDenominations.forEach(addPostfixesOf)
|
denomination.alternativeDenominations.forEach(addPostfixesOf)
|
||||||
}
|
}
|
||||||
this.possiblePostFixes = Array.from(possiblePostFixes)
|
|
||||||
this.possiblePostFixes.sort((a, b) => b.length - a.length)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,16 +66,12 @@ export class Unit {
|
||||||
}
|
}
|
||||||
// Some keys do have unit handling
|
// Some keys do have unit handling
|
||||||
|
|
||||||
const defaultSet = json.applicableUnits.filter(u => u.default === true)
|
if(json.applicableUnits.some(denom => denom.useAsDefaultInput !== undefined)){
|
||||||
// No default is defined - we pick the first as default
|
json.applicableUnits.forEach(denom => {
|
||||||
if (defaultSet.length === 0) {
|
denom.useAsDefaultInput = denom.useAsDefaultInput ?? false
|
||||||
json.applicableUnits[0].default = true
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that there are not multiple defaults
|
|
||||||
if (defaultSet.length > 1) {
|
|
||||||
throw `Multiple units are set as default: they have canonical values of ${defaultSet.map(u => u.canonicalDenomination).join(", ")}`
|
|
||||||
}
|
|
||||||
const applicable = json.applicableUnits.map((u, i) => new Denomination(u, `${ctx}.units[${i}]`))
|
const applicable = json.applicableUnits.map((u, i) => new Denomination(u, `${ctx}.units[${i}]`))
|
||||||
return new Unit(appliesTo, applicable, json.eraseInvalidValues ?? false)
|
return new Unit(appliesTo, applicable, json.eraseInvalidValues ?? false)
|
||||||
}
|
}
|
||||||
|
@ -96,12 +87,13 @@ export class Unit {
|
||||||
/**
|
/**
|
||||||
* Finds which denomination is applicable and gives the stripped value back
|
* Finds which denomination is applicable and gives the stripped value back
|
||||||
*/
|
*/
|
||||||
findDenomination(valueWithDenom: string): [string, Denomination] {
|
findDenomination(valueWithDenom: string, country: () => string): [string, Denomination] {
|
||||||
if (valueWithDenom === undefined) {
|
if (valueWithDenom === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const defaultDenom = this.getDefaultDenomination(country)
|
||||||
for (const denomination of this.denominationsSorted) {
|
for (const denomination of this.denominationsSorted) {
|
||||||
const bare = denomination.StrippedValue(valueWithDenom)
|
const bare = denomination.StrippedValue(valueWithDenom, defaultDenom === denomination)
|
||||||
if (bare !== null) {
|
if (bare !== null) {
|
||||||
return [bare, denomination]
|
return [bare, denomination]
|
||||||
}
|
}
|
||||||
|
@ -109,11 +101,11 @@ export class Unit {
|
||||||
return [undefined, undefined]
|
return [undefined, undefined]
|
||||||
}
|
}
|
||||||
|
|
||||||
asHumanLongValue(value: string): BaseUIElement {
|
asHumanLongValue(value: string, country: () => string): BaseUIElement {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const [stripped, denom] = this.findDenomination(value)
|
const [stripped, denom] = this.findDenomination(value, country)
|
||||||
const human = stripped === "1" ? denom?.humanSingular : denom?.human
|
const human = stripped === "1" ? denom?.humanSingular : denom?.human
|
||||||
if (human === undefined) {
|
if (human === undefined) {
|
||||||
return new FixedUiElement(stripped ?? value);
|
return new FixedUiElement(stripped ?? value);
|
||||||
|
@ -124,24 +116,46 @@ export class Unit {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value without any (sub)parts of any denomination - usefull as preprocessing step for validating inputs.
|
public getDefaultInput(country: () => string | string[]) {
|
||||||
* E.g.
|
console.log("Searching the default denomination for input", country)
|
||||||
* if 'megawatt' is a possible denomination, then '5 Meg' will be rewritten to '5' (which can then be validated as a valid pnat)
|
for (const denomination of this.denominations) {
|
||||||
*
|
if (denomination.useAsDefaultInput === true) {
|
||||||
* Returns the original string if nothign matches
|
return denomination
|
||||||
*/
|
}
|
||||||
stripUnitParts(str: string) {
|
if (denomination.useAsDefaultInput === undefined || denomination.useAsDefaultInput === false) {
|
||||||
if (str === undefined) {
|
continue
|
||||||
return undefined;
|
}
|
||||||
|
let countries: string | string[] = country()
|
||||||
|
if (typeof countries === "string") {
|
||||||
|
countries = countries.split(",")
|
||||||
|
}
|
||||||
|
const denominationCountries: string[] = denomination.useAsDefaultInput
|
||||||
|
if (countries.some(country => denominationCountries.indexOf(country) >= 0)) {
|
||||||
|
return denomination
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.denominations[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const denominationPart of this.possiblePostFixes) {
|
public getDefaultDenomination(country: () => string){
|
||||||
if (str.endsWith(denominationPart)) {
|
for (const denomination of this.denominations) {
|
||||||
return str.substring(0, str.length - denominationPart.length).trim()
|
if (denomination.useIfNoUnitGiven === true || denomination.canonical === "") {
|
||||||
|
return denomination
|
||||||
}
|
}
|
||||||
|
if (denomination.useIfNoUnitGiven === undefined || denomination.useIfNoUnitGiven === false) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let countries: string | string[] = country()
|
||||||
|
if (typeof countries === "string") {
|
||||||
|
countries = countries.split(",")
|
||||||
|
}
|
||||||
|
const denominationCountries: string[] = denomination.useIfNoUnitGiven
|
||||||
|
if (countries.some(country => denominationCountries.indexOf(country) >= 0)) {
|
||||||
|
return denomination
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.denominations[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import BaseUIElement from "../BaseUIElement";
|
||||||
import {Chart, ChartConfiguration, ChartType, DefaultDataPoint, registerables} from 'chart.js';
|
import {Chart, ChartConfiguration, ChartType, DefaultDataPoint, registerables} from 'chart.js';
|
||||||
Chart.register(...registerables);
|
Chart?.register(...(registerables ?? []));
|
||||||
|
|
||||||
|
|
||||||
export default class ChartJs<
|
export default class ChartJs<
|
||||||
|
|
|
@ -78,7 +78,6 @@ export class SubtleButton extends UIElement {
|
||||||
})
|
})
|
||||||
const loading = new Lazy(() => new Loading(loadingText) )
|
const loading = new Lazy(() => new Loading(loadingText) )
|
||||||
return new VariableUiElement(state.map(st => {
|
return new VariableUiElement(state.map(st => {
|
||||||
console.log("State is: ", st)
|
|
||||||
if(st === "idle"){
|
if(st === "idle"){
|
||||||
return button
|
return button
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {QueryParameters} from "../../Logic/Web/QueryParameters";
|
||||||
import {TagUtils} from "../../Logic/Tags/TagUtils";
|
import {TagUtils} from "../../Logic/Tags/TagUtils";
|
||||||
import {InputElement} from "../Input/InputElement";
|
import {InputElement} from "../Input/InputElement";
|
||||||
import {DropDown} from "../Input/DropDown";
|
import {DropDown} from "../Input/DropDown";
|
||||||
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||||
|
|
||||||
export default class FilterView extends VariableUiElement {
|
export default class FilterView extends VariableUiElement {
|
||||||
constructor(filteredLayer: UIEventSource<FilteredLayer[]>,
|
constructor(filteredLayer: UIEventSource<FilteredLayer[]>,
|
||||||
|
@ -91,7 +92,7 @@ export default class FilterView extends VariableUiElement {
|
||||||
if (filteredLayer.layerDef.name === undefined) {
|
if (filteredLayer.layerDef.name === undefined) {
|
||||||
// Name is not defined: we hide this one
|
// Name is not defined: we hide this one
|
||||||
return new Toggle(
|
return new Toggle(
|
||||||
filteredLayer?.layerDef?.description?.Clone()?.SetClass("subtle") ,
|
new FixedUiElement(filteredLayer?.layerDef?.id ).SetClass("block") ,
|
||||||
undefined,
|
undefined,
|
||||||
state?.featureSwitchIsDebugging
|
state?.featureSwitchIsDebugging
|
||||||
);
|
);
|
||||||
|
|
|
@ -90,7 +90,7 @@ export class TextFieldDef {
|
||||||
if (options.unit !== undefined) {
|
if (options.unit !== undefined) {
|
||||||
// Reformatting is handled by the unit in this case
|
// Reformatting is handled by the unit in this case
|
||||||
options["isValid"] = str => {
|
options["isValid"] = str => {
|
||||||
const denom = options.unit.findDenomination(str);
|
const denom = options.unit.findDenomination(str, options?.country);
|
||||||
if (denom === undefined) {
|
if (denom === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ export class TextFieldDef {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
unitDropDown.GetValue().setData(unit.defaultDenom)
|
unitDropDown.GetValue().setData(unit.getDefaultInput(options.country))
|
||||||
unitDropDown.SetClass("w-min")
|
unitDropDown.SetClass("w-min")
|
||||||
|
|
||||||
const fixedDenom = unit.denominations.length === 1 ? unit.denominations[0] : undefined
|
const fixedDenom = unit.denominations.length === 1 ? unit.denominations[0] : undefined
|
||||||
|
@ -169,7 +169,7 @@ export class TextFieldDef {
|
||||||
},
|
},
|
||||||
(valueWithDenom: string) => {
|
(valueWithDenom: string) => {
|
||||||
// Take the value from OSM and feed it into the textfield and the dropdown
|
// Take the value from OSM and feed it into the textfield and the dropdown
|
||||||
const withDenom = unit.findDenomination(valueWithDenom);
|
const withDenom = unit.findDenomination(valueWithDenom, options?.country);
|
||||||
if (withDenom === undefined) {
|
if (withDenom === undefined) {
|
||||||
// Not a valid value at all - we give it undefined and leave the details up to the other elements (but we keep the previous denomination)
|
// Not a valid value at all - we give it undefined and leave the details up to the other elements (but we keep the previous denomination)
|
||||||
return [undefined, fixedDenom]
|
return [undefined, fixedDenom]
|
||||||
|
|
|
@ -617,6 +617,7 @@ export default class TagRenderingQuestion extends Combine {
|
||||||
const tagsData = tags.data;
|
const tagsData = tags.data;
|
||||||
const feature = state?.allElements?.ContainingFeatures?.get(tagsData.id)
|
const feature = state?.allElements?.ContainingFeatures?.get(tagsData.id)
|
||||||
const center = feature != undefined ? GeoOperations.centerpointCoordinates(feature) : [0, 0]
|
const center = feature != undefined ? GeoOperations.centerpointCoordinates(feature) : [0, 0]
|
||||||
|
console.log("Creating a tr-question with applicableUnit", applicableUnit)
|
||||||
const input: InputElement<string> = ValidatedTextField.ForType(configuration.freeform.type)?.ConstructInputElement({
|
const input: InputElement<string> = ValidatedTextField.ForType(configuration.freeform.type)?.ConstructInputElement({
|
||||||
country: () => tagsData._country,
|
country: () => tagsData._country,
|
||||||
location: [center[1], center[0]],
|
location: [center[1], center[0]],
|
||||||
|
|
|
@ -1273,6 +1273,9 @@ export default class SpecialVisualizations {
|
||||||
const tagRendering = layer.tagRenderings.find(tr => tr.id === tagRenderingId)
|
const tagRendering = layer.tagRenderings.find(tr => tr.id === tagRenderingId)
|
||||||
tagRenderings.push([layer, tagRendering])
|
tagRenderings.push([layer, tagRendering])
|
||||||
}
|
}
|
||||||
|
if(tagRenderings.length === 0){
|
||||||
|
throw "Could not create stolen tagrenddering: tagRenderings not found"
|
||||||
|
}
|
||||||
return new VariableUiElement(featureTags.map(tags => {
|
return new VariableUiElement(featureTags.map(tags => {
|
||||||
const featureId = tags[featureIdKey]
|
const featureId = tags[featureIdKey]
|
||||||
if (featureId === undefined) {
|
if (featureId === undefined) {
|
||||||
|
|
4
Utils.ts
|
@ -151,8 +151,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NoNull<T>(array: T[]): T[] {
|
public static NoNull<T>(array: T[]): NonNullable<T>[] {
|
||||||
return array?.filter(o => o !== undefined && o !== null)
|
return <any> array?.filter(o => o !== undefined && o !== null)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Hist(array: string[]): Map<string, number> {
|
public static Hist(array: string[]): Map<string, number> {
|
||||||
|
|
|
@ -271,6 +271,9 @@
|
||||||
"smoking",
|
"smoking",
|
||||||
"service:electricity",
|
"service:electricity",
|
||||||
"dog-access",
|
"dog-access",
|
||||||
|
"internet",
|
||||||
|
"internet-fee",
|
||||||
|
"internet-ssid",
|
||||||
"reviews"
|
"reviews"
|
||||||
],
|
],
|
||||||
"filter": [
|
"filter": [
|
||||||
|
|
|
@ -185,6 +185,7 @@
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"meter"
|
"meter"
|
||||||
],
|
],
|
||||||
|
"useIfNoUnitGiven": true,
|
||||||
"human": {
|
"human": {
|
||||||
"en": "meter",
|
"en": "meter",
|
||||||
"fr": "mètre",
|
"fr": "mètre",
|
||||||
|
@ -193,7 +194,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": true,
|
"useAsDefaultInput": true,
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
|
|
@ -467,10 +467,12 @@
|
||||||
"units": [
|
"units": [
|
||||||
{
|
{
|
||||||
"appliesToKey": [
|
"appliesToKey": [
|
||||||
"kerb:height"
|
"kerb:height",
|
||||||
|
"width"
|
||||||
],
|
],
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
|
"useIfNoUnitGiven": true,
|
||||||
"canonicalDenomination": "m",
|
"canonicalDenomination": "m",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"meter"
|
"meter"
|
||||||
|
@ -483,7 +485,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": true,
|
"useAsDefaultInput": true,
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
|
|
@ -764,6 +764,9 @@
|
||||||
},
|
},
|
||||||
"service:electricity",
|
"service:electricity",
|
||||||
"dog-access",
|
"dog-access",
|
||||||
|
"internet",
|
||||||
|
"internet-fee",
|
||||||
|
"internet-ssid",
|
||||||
"reviews"
|
"reviews"
|
||||||
],
|
],
|
||||||
"filter": [
|
"filter": [
|
||||||
|
|
|
@ -80,7 +80,10 @@
|
||||||
"phone",
|
"phone",
|
||||||
"email",
|
"email",
|
||||||
"website",
|
"website",
|
||||||
"wheelchair-access"
|
"wheelchair-access",
|
||||||
|
"internet",
|
||||||
|
"internet-fee",
|
||||||
|
"internet-ssid"
|
||||||
],
|
],
|
||||||
"allowMove": {
|
"allowMove": {
|
||||||
"enableImproveAccuracy": true,
|
"enableImproveAccuracy": true,
|
||||||
|
|
|
@ -1,3 +1,45 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<path d="M 0.5 3 C 0.223 3 0 3.223 0 3.5 L 0 4 L 0 8 L 0 9 L 0 9.5 L 0 11 L 1 11 L 1 9.5 L 1 9 L 13 9 L 13 10.5 L 13 11 L 13.5 11 L 14 11 L 14 10.5 L 14 9 L 14 8 L 14 6 L 14 5.5 C 14 5.223 13.777 5 13.5 5 C 13.223 5 13 5.223 13 5.5 L 13 6 L 13 8 L 1 8 L 1 4 L 1 3.5 C 1 3.223 0.777 3 0.5 3 z M 3.5 4 C 2.671573 4 2 4.671573 2 5.5 C 2 6.328427 2.671573 7 3.5 7 C 4.328427 7 5 6.328427 5 5.5 C 5 4.671573 4.328427 4 3.5 4 z M 6 5 L 6 7 L 12 7 C 12 6 10.963825 5 10 5 L 6 5 z"/>
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 500 500"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="hotel.svg"
|
||||||
|
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#111111"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="1"
|
||||||
|
showgrid="false"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:zoom="0.5912918"
|
||||||
|
inkscape:cx="43.125915"
|
||||||
|
inkscape:cy="341.6249"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1007"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4">
|
||||||
|
<sodipodi:guide
|
||||||
|
position="-213.39489,250.02313"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide827" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
d="m 20.793355,103.8662 c -9.838754,0 -17.7594848,7.92073 -17.7594848,17.75948 v 17.75948 142.07589 35.51898 17.75949 53.27845 H 38.552842 V 334.73952 316.98003 H 464.78049 v 53.27845 17.75949 h 17.7595 17.75948 v -17.75949 -53.27845 -35.51898 -71.03793 -17.75949 c 0,-9.83876 -7.92073,-17.75949 -17.75948,-17.75949 -9.83876,0 -17.7595,7.92073 -17.7595,17.75949 v 17.75949 71.03793 H 38.552842 V 139.38516 121.62568 c 0,-9.83875 -7.920731,-17.75948 -17.759487,-17.75948 z m 106.556915,35.51896 c -29.424876,0 -53.278458,23.85359 -53.278458,53.27847 0,29.42487 23.853582,53.27845 53.278458,53.27845 29.42487,0 53.27845,-23.85358 53.27845,-53.27845 0,-29.42488 -23.85358,-53.27847 -53.27845,-53.27847 z m 88.79743,35.51898 v 71.03794 h 213.11382 c 0,-35.51896 -36.80387,-71.03794 -71.03793,-71.03794 z"
|
||||||
|
id="path2"
|
||||||
|
style="stroke-width:35.519" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 569 B After Width: | Height: | Size: 2 KiB |
|
@ -456,7 +456,6 @@
|
||||||
{
|
{
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
"default": true,
|
|
||||||
"canonicalDenomination": "",
|
"canonicalDenomination": "",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"mm",
|
"mm",
|
||||||
|
|
|
@ -178,8 +178,6 @@
|
||||||
"centroid"
|
"centroid"
|
||||||
],
|
],
|
||||||
"icon": {
|
"icon": {
|
||||||
"render": null,
|
|
||||||
"condition": "indoor=room",
|
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
|
|
|
@ -339,8 +339,7 @@
|
||||||
"nl": "centimeter",
|
"nl": "centimeter",
|
||||||
"de": "Zentimeter",
|
"de": "Zentimeter",
|
||||||
"fr": "centimètre"
|
"fr": "centimètre"
|
||||||
},
|
}
|
||||||
"default": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"canonicalDenomination": "m",
|
"canonicalDenomination": "m",
|
||||||
|
|
|
@ -110,16 +110,19 @@
|
||||||
"allowSplit": true,
|
"allowSplit": true,
|
||||||
"mapRendering": [
|
"mapRendering": [
|
||||||
{
|
{
|
||||||
"render": null,
|
|
||||||
"icon": {
|
"icon": {
|
||||||
|
"render": null,
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": "maxspeed~[1-9]0|1[0-4]0",
|
"if": "maxspeed~[1-9]0|1[0-4]0",
|
||||||
|
"then": "./assets/themes/maxspeed/maxspeed_{maxspeed} mph.svg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "maxspeed~[1-9]0|1[0-4]0 mph",
|
||||||
"then": "./assets/themes/maxspeed/maxspeed_{maxspeed}.svg"
|
"then": "./assets/themes/maxspeed/maxspeed_{maxspeed}.svg"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"condition": "maxspeed!=30",
|
|
||||||
"iconSize": {
|
"iconSize": {
|
||||||
"render": "32,32,center"
|
"render": "32,32,center"
|
||||||
},
|
},
|
||||||
|
@ -154,7 +157,6 @@
|
||||||
"kmh",
|
"kmh",
|
||||||
"kph"
|
"kph"
|
||||||
],
|
],
|
||||||
"default": true,
|
|
||||||
"human": {
|
"human": {
|
||||||
"en": "kilometers/hour",
|
"en": "kilometers/hour",
|
||||||
"ca": "quilòmetres/hora",
|
"ca": "quilòmetres/hora",
|
||||||
|
@ -172,6 +174,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"canonicalDenomination": "mph",
|
"canonicalDenomination": "mph",
|
||||||
|
"useIfNoUnitGiven": ["gb","us"],
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"m/u",
|
"m/u",
|
||||||
"mh",
|
"mh",
|
||||||
|
|
|
@ -164,6 +164,15 @@
|
||||||
"fr": "Il n'y a pas de places de stationnement pour personnes à mobilité réduite"
|
"fr": "Il n'y a pas de places de stationnement pour personnes à mobilité réduite"
|
||||||
},
|
},
|
||||||
"hideInAnswer": true
|
"hideInAnswer": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "capacity:disabled=0",
|
||||||
|
"then": {
|
||||||
|
"en": "There are no disabled parking spots",
|
||||||
|
"nl": "Er zijn geen parkeerplaatsen voor gehandicapten",
|
||||||
|
"de": "Es gibt keine barrierefreien Stellplätze",
|
||||||
|
"fr": "Il n'y a pas de places de stationnement pour personnes à mobilité réduite"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"question": {
|
"question": {
|
||||||
|
@ -247,9 +256,9 @@
|
||||||
"iconBadges": [
|
"iconBadges": [
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"and": [
|
"or": [
|
||||||
"capacity:disabled~*",
|
"capacity:disabled>0",
|
||||||
"capacity:disabled!=no"
|
"capacity:disabled=yes"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"then": "circle:white;./assets/layers/toilet/wheelchair.svg"
|
"then": "circle:white;./assets/layers/toilet/wheelchair.svg"
|
||||||
|
|
10
assets/layers/parking_spaces/license_info.json
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "parking_space.svg",
|
||||||
|
"license": "CC0",
|
||||||
|
"authors": [
|
||||||
|
"Robin van der Linde"
|
||||||
|
],
|
||||||
|
"sources": []
|
||||||
|
}
|
||||||
|
]
|
70
assets/layers/parking_spaces/parking_space.svg
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
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"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.29166 132.29167"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||||
|
sodipodi:docname="Parking_space.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="105.28861"
|
||||||
|
inkscape:cy="436.23499"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2149"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Laag 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#1d5485;stroke-width:5px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 26.458333,121.70833 0,-111.124997 h 79.374997 l 0,111.124997"
|
||||||
|
id="path833"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<g
|
||||||
|
aria-label="P"
|
||||||
|
id="text833"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:68.771px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.71928">
|
||||||
|
<path
|
||||||
|
d="m 82.499093,56.25664 q 0,3.32438 -1.175286,6.178645 -1.141706,2.820686 -3.22364,4.90262 -2.585629,2.585629 -6.111486,3.895233 -3.525857,1.276025 -8.898592,1.276025 H 56.44133 V 91.145836 H 49.792571 V 41.145824 h 13.566155 q 4.499665,0 7.622567,0.772331 3.122902,0.738751 5.540633,2.350571 2.854265,1.914037 4.398926,4.768302 1.578241,2.854265 1.578241,7.219612 z m -6.917396,0.167898 q 0,-2.585628 -0.906649,-4.499665 -0.906649,-1.914037 -2.753526,-3.122902 -1.611821,-1.040968 -3.693755,-1.477502 -2.048355,-0.470115 -5.204837,-0.470115 h -6.5816 v 19.979858 h 5.607792 q 4.029551,0 6.54802,-0.705172 2.51847,-0.738751 4.09671,-2.316992 1.578241,-1.61182 2.216253,-3.391538 0.671592,-1.779719 0.671592,-3.995972 z"
|
||||||
|
style="stroke-width:1.71928"
|
||||||
|
id="path835" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
155
assets/layers/parking_spaces/parking_spaces.json
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
{
|
||||||
|
"id": "parking_spaces",
|
||||||
|
"name": {
|
||||||
|
"en": "Parking Spaces"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"en": "Layer showing individual parking spaces."
|
||||||
|
},
|
||||||
|
"minzoom": 20,
|
||||||
|
"source": {
|
||||||
|
"osmTags": "amenity=parking_space"
|
||||||
|
},
|
||||||
|
"tagRenderings": [
|
||||||
|
{
|
||||||
|
"id": "type",
|
||||||
|
"question": {
|
||||||
|
"en": "What kind of parking space is this?"
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "parking_space=",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a normal parking space"
|
||||||
|
},
|
||||||
|
"hideInAnswer": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=normal",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a normal parking space."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=disabled",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a disabled parking space."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=private",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a private parking space."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=charging",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for charging vehicles."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=delivery",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for deliveries."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=hgv",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for heavy goods vehicles."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=caravan",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for caravans or RVs."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=bus",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for buses."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=motorcycle",
|
||||||
|
"then": {
|
||||||
|
"en": "This is parking space reserved for motorcycles."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=parent",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a parking space reserved for parents with children."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=staff",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a parking space reserved for staff."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=taxi",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a parking space reserved for taxis."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=trailer",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a parking space reserved for vehicles towing a trailer."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "parking_space=car_sharing",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a parking space reserved for car sharing."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "capacity",
|
||||||
|
"render": {
|
||||||
|
"en": "This parking spaces has {capacity} spaces."
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "capacity=1",
|
||||||
|
"then": {
|
||||||
|
"en": "This parking space has 1 space."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": {
|
||||||
|
"render": {
|
||||||
|
"en": "Parking Space"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mapRendering": [
|
||||||
|
{
|
||||||
|
"icon": {
|
||||||
|
"render": "./assets/layers/parking_spaces/parking_space.svg",
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "parking_space=disabled",
|
||||||
|
"then": "./assets/layers/toilet/wheelchair.svg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"iconSize": "20,20,center",
|
||||||
|
"location": [
|
||||||
|
"point",
|
||||||
|
"centroid"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "#696969",
|
||||||
|
"width": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -201,6 +201,9 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"internet",
|
||||||
|
"internet-fee",
|
||||||
|
"internet-ssid",
|
||||||
"questions",
|
"questions",
|
||||||
"reviews"
|
"reviews"
|
||||||
],
|
],
|
||||||
|
|
|
@ -264,7 +264,7 @@
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": "access=public",
|
"if": "access=yes",
|
||||||
"then": {
|
"then": {
|
||||||
"nl": "Publiek toegankelijk",
|
"nl": "Publiek toegankelijk",
|
||||||
"fr": "Accessible au public",
|
"fr": "Accessible au public",
|
||||||
|
@ -309,6 +309,19 @@
|
||||||
"de": "Der Sportplatz ist nicht öffentlich zugänglich (es ist ein privater Sportplatz)",
|
"de": "Der Sportplatz ist nicht öffentlich zugänglich (es ist ein privater Sportplatz)",
|
||||||
"es": "Privada - no accesible al público"
|
"es": "Privada - no accesible al público"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "access=public",
|
||||||
|
"then": {
|
||||||
|
"nl": "Publiek toegankelijk",
|
||||||
|
"fr": "Accessible au public",
|
||||||
|
"en": "Public access",
|
||||||
|
"it": "Aperto al pubblico",
|
||||||
|
"ru": "Свободный доступ",
|
||||||
|
"de": "Der Sportplatz ist öffentlich zugänglich",
|
||||||
|
"es": "Acceso público"
|
||||||
|
},
|
||||||
|
"hideInAnswer": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
],
|
],
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
|
"useIfNoUnitGiven": true,
|
||||||
"canonicalDenomination": "m",
|
"canonicalDenomination": "m",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"meter"
|
"meter"
|
||||||
|
@ -74,7 +75,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": true,
|
"useAsDefaultInput": true,
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
|
|
@ -1148,5 +1148,110 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"internet": {
|
||||||
|
"question": {
|
||||||
|
"en": "Does this place offer internet access?",
|
||||||
|
"nl": "Biedt deze plaats internettoegang aan?"
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "internet_access=wlan",
|
||||||
|
"then": {
|
||||||
|
"en": "This place offers wireless internet access",
|
||||||
|
"nl": "Deze plaats biedt draadloze internettoegang aan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access=no",
|
||||||
|
"then": {
|
||||||
|
"en": "This place <b>does not</b> offer internet access",
|
||||||
|
"nl": "Deze plaats biedt <b>geen</b> internettoegang aan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access=yes",
|
||||||
|
"then": {
|
||||||
|
"en": "This place offers internet access",
|
||||||
|
"nl": "Deze plaats biedt internettoegang aan"
|
||||||
|
},
|
||||||
|
"hideInAnswer": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access=terminal",
|
||||||
|
"then": {
|
||||||
|
"en": "This place offers internet access via a terminal or computer",
|
||||||
|
"nl": "Deze plaats biedt internettoegang via een terminal of computer aan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access=wired",
|
||||||
|
"then": {
|
||||||
|
"en": "This place offers wired internet access",
|
||||||
|
"nl": "Deze plaats biedt bedrade internettoegang aan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"internet-fee": {
|
||||||
|
"condition": {
|
||||||
|
"and": [
|
||||||
|
"internet_access!=no",
|
||||||
|
"internet_access!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"en": "Is there a fee for internet access?",
|
||||||
|
"nl": "Zijn er kosten voor internettoegang?"
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "internet_access:fee=yes",
|
||||||
|
"then": {
|
||||||
|
"en": "There is a fee for the internet access at this place",
|
||||||
|
"nl": "Er zijn kosten voor internettoegang op deze plaats"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access:fee=no",
|
||||||
|
"then": {
|
||||||
|
"en": "Internet access is free at this place",
|
||||||
|
"nl": "Internettoegang is gratis op deze plaats"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "internet_access:fee=customers",
|
||||||
|
"then": {
|
||||||
|
"en": "Internet access is free at this place, for customers only",
|
||||||
|
"nl": "Internettoegang is gratis op deze plaats, alleen voor klanten"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"internet-ssid": {
|
||||||
|
"condition": "internet_access=wlan",
|
||||||
|
"question": {
|
||||||
|
"en": "What is the network name for the wireless internet access?",
|
||||||
|
"nl": "Wat is de netwerknaam voor de draadloze internettoegang?"
|
||||||
|
},
|
||||||
|
"freeform": {
|
||||||
|
"key": "internet_access:ssid",
|
||||||
|
"type": "string",
|
||||||
|
"placeholder": {
|
||||||
|
"en": "Enter the network name",
|
||||||
|
"nl": "Voer de netwerknaam in"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "internet_access:ssid=Telekom",
|
||||||
|
"then": "Telekom",
|
||||||
|
"hideInAnswer": "_country!=de"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"render": {
|
||||||
|
"en": "The network name is <b>{internet_access:ssid}</b>",
|
||||||
|
"nl": "De netwerknaam is <b>{internet_access:ssid}</b>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -132,8 +132,7 @@
|
||||||
"ca": " metre",
|
"ca": " metre",
|
||||||
"nb_NO": " meter",
|
"nb_NO": " meter",
|
||||||
"es": " metro"
|
"es": " metro"
|
||||||
},
|
}
|
||||||
"default": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"canonicalDenomination": "ft",
|
"canonicalDenomination": "ft",
|
||||||
|
|
18
assets/themes/hotels/hotels.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"id": "hotels",
|
||||||
|
"title": {
|
||||||
|
"en": "Hotels"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"en": "On this map, you'll find hotels in your area"
|
||||||
|
},
|
||||||
|
"maintainer": "MapComplete",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"icon": "./assets/layers/hotel/hotel.svg",
|
||||||
|
"startLat": 50.8552,
|
||||||
|
"startLon": 4.3755,
|
||||||
|
"startZoom": 13,
|
||||||
|
"layers": [
|
||||||
|
"hotel"
|
||||||
|
]
|
||||||
|
}
|
|
@ -207,6 +207,10 @@
|
||||||
"if": "theme=healthcare",
|
"if": "theme=healthcare",
|
||||||
"then": "./assets/layers/doctors/doctors.svg"
|
"then": "./assets/layers/doctors/doctors.svg"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"if": "theme=hotels",
|
||||||
|
"then": "./assets/layers/hotel/hotel.svg"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"if": "theme=indoors",
|
"if": "theme=indoors",
|
||||||
"then": "./assets/layers/entrance/entrance.svg"
|
"then": "./assets/layers/entrance/entrance.svg"
|
||||||
|
|
|
@ -1,142 +1,142 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"path": "maxspeed_10.svg",
|
"path": "maxspeed_10 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_100.svg",
|
"path": "maxspeed_100 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_110.svg",
|
"path": "maxspeed_110 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_120.svg",
|
"path": "maxspeed_120 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_130.svg",
|
"path": "maxspeed_130 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_140.svg",
|
"path": "maxspeed_140 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_20.svg",
|
"path": "maxspeed_20 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_30.svg",
|
"path": "maxspeed_30 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_40.svg",
|
"path": "maxspeed_40 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_50.svg",
|
"path": "maxspeed_50 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_60.svg",
|
"path": "maxspeed_60 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_70.svg",
|
"path": "maxspeed_70 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_80.svg",
|
"path": "maxspeed_80 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "maxspeed_90.svg",
|
"path": "maxspeed_90 mph.svg",
|
||||||
"license": "CC 4.0",
|
"license": "CC 4.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
"yopaseopor"
|
"yopaseopor"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30.svg"
|
"https://raw.githubusercontent.com/yopaseopor/beta_preset_josm/master/ES/traffic_signs/ES/ES_R301-30 mph.svg"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -45,6 +45,7 @@
|
||||||
"startZoom": 12,
|
"startZoom": 12,
|
||||||
"widenFactor": 1.2,
|
"widenFactor": 1.2,
|
||||||
"layers": [
|
"layers": [
|
||||||
"parking"
|
"parking",
|
||||||
|
"parking_spaces"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -3566,7 +3566,7 @@
|
||||||
},
|
},
|
||||||
"width": {
|
"width": {
|
||||||
"question": "Wie breit ist diese Tür bzw. dieser Eingang?",
|
"question": "Wie breit ist diese Tür bzw. dieser Eingang?",
|
||||||
"render": "Diese Tür hat eine Durchgangsbreite von {canonical(width)} Meter"
|
"render": "Diese Tür hat eine Durchgangsbreite von {canonical(width)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -4249,10 +4249,51 @@
|
||||||
},
|
},
|
||||||
"question": "Welche Bauform hat der Hydrant?",
|
"question": "Welche Bauform hat der Hydrant?",
|
||||||
"render": " Hydranten-Typ: {fire_hydrant:type}"
|
"render": " Hydranten-Typ: {fire_hydrant:type}"
|
||||||
|
},
|
||||||
|
"hydrant-couplings-diameters": {
|
||||||
|
"question": "Welchen Durchmesser haben die Kupplungen dieses Hydranten?",
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Kupplungsdurchmesser"
|
||||||
|
},
|
||||||
|
"render": "Kupplungsdurchmesser: {couplings:diameters}"
|
||||||
|
},
|
||||||
|
"hydrant-couplings": {
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Art der Kupplung"
|
||||||
|
},
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Storz-Kupplung"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "UNI-Kupplung"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Barcelona-Kupplung"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Welche Art von Kupplungen hat dieser Hydrant?",
|
||||||
|
"render": "Kupplungen: {couplings:type}"
|
||||||
|
},
|
||||||
|
"hydrant-diameter": {
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Rohrdurchmesser"
|
||||||
|
},
|
||||||
|
"question": "Was ist der Rohrdurchmesser dieses Hydranten?",
|
||||||
|
"render": "Rohrdurchmesser: {canonical(fire_hydrant:diameter)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"render": "Hydrant"
|
"render": "Hydrant"
|
||||||
|
},
|
||||||
|
"units": {
|
||||||
|
"0": {
|
||||||
|
"applicableUnits": {
|
||||||
|
"0": {
|
||||||
|
"human": "Millimeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"indoors": {
|
"indoors": {
|
||||||
|
@ -4366,7 +4407,7 @@
|
||||||
"then": "Der Bordstein hat kein taktiles Pflaster."
|
"then": "Der Bordstein hat kein taktiles Pflaster."
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Der Bordstein hat ein taktiles Pflaster, das aber falsch ist"
|
"then": "Der Bordstein hat ein taktiles Pflaster, das aber falsch ist."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Gibt es am Bordstein ein taktiles Pflaster?"
|
"question": "Gibt es am Bordstein ein taktiles Pflaster?"
|
||||||
|
@ -4648,7 +4689,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Wie hoch ist die zulässige Höchstgeschwindigkeit, die man auf dieser Straße fahren darf?",
|
"question": "Wie hoch ist die zulässige Höchstgeschwindigkeit, die man auf dieser Straße fahren darf?",
|
||||||
"render": "Die zulässige Höchstgeschwindigkeit auf dieser Straße ist {maxspeed}"
|
"render": "Die zulässige Höchstgeschwindigkeit auf dieser Straße ist {canonical(maxspeed)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
|
|
@ -3566,7 +3566,7 @@
|
||||||
},
|
},
|
||||||
"width": {
|
"width": {
|
||||||
"question": "What is the width of this door/entrance?",
|
"question": "What is the width of this door/entrance?",
|
||||||
"render": "This door has a width of {canonical(width)} meter"
|
"render": "This door has a width of {canonical(width)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -4438,7 +4438,7 @@
|
||||||
"then": "This kerb does not have tactile paving."
|
"then": "This kerb does not have tactile paving."
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"then": "This kerb has tactile paving, but it is incorrect"
|
"then": "This kerb has tactile paving, but it is incorrect."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Is there tactile paving at this kerb?"
|
"question": "Is there tactile paving at this kerb?"
|
||||||
|
@ -4720,7 +4720,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "What is the legal maximum speed one is allowed to drive on this road?",
|
"question": "What is the legal maximum speed one is allowed to drive on this road?",
|
||||||
"render": "The maximum allowed speed on this road is {maxspeed}"
|
"render": "The maximum allowed speed on this road is {canonical(maxspeed)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
|
|
@ -3049,7 +3049,7 @@
|
||||||
"then": "Cette bordure n'a pas de revêtement podotactile."
|
"then": "Cette bordure n'a pas de revêtement podotactile."
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Cette bordure a un pavage tactile, mais il est incorrect"
|
"then": "Cette bordure a un pavage tactile, mais il est incorrect."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Y a-t-il un revêtement tactile sur cette bordure ?"
|
"question": "Y a-t-il un revêtement tactile sur cette bordure ?"
|
||||||
|
|
|
@ -3406,6 +3406,9 @@
|
||||||
"presets": {
|
"presets": {
|
||||||
"0": {
|
"0": {
|
||||||
"title": "een toegang"
|
"title": "een toegang"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"title": "een binnendeur"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tagRenderings": {
|
"tagRenderings": {
|
||||||
|
@ -3509,7 +3512,7 @@
|
||||||
},
|
},
|
||||||
"width": {
|
"width": {
|
||||||
"question": "Wat is de breedte van deze deur/toegang?",
|
"question": "Wat is de breedte van deze deur/toegang?",
|
||||||
"render": "Deze deur heeft een breedte van {canonical(width)} meter"
|
"render": "Deze deur heeft een breedte van {canonical(width)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -4221,7 +4224,43 @@
|
||||||
"description": "Een basis voor indoor-navigatie: toont binnenruimtes",
|
"description": "Een basis voor indoor-navigatie: toont binnenruimtes",
|
||||||
"name": "Binnenruimtes",
|
"name": "Binnenruimtes",
|
||||||
"title": {
|
"title": {
|
||||||
"render": "Binnenruimte {name}"
|
"render": "Binnenruimte {name}",
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Binnenruimte {name}"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"then": "Binnendeur {name}"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"then": "Gang in gebouw {name}"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Gebied in gebouw {name}"
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"then": "Verdieping in gebouw {name}"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Muur in gebouw {name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tagRenderings": {
|
||||||
|
"name": {
|
||||||
|
"render": "Deze ruimte heet {name}",
|
||||||
|
"question": "Wat is de naam van deze ruimte?",
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Naam van de ruimte"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ref": {
|
||||||
|
"question": "Wat is het referentienummer van deze ruimte?",
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Referentienummer van de ruimte (bv. '1.1' of A1' )"
|
||||||
|
},
|
||||||
|
"render": "Deze ruimte heeft het referentienummer {ref}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"information_board": {
|
"information_board": {
|
||||||
|
@ -4264,7 +4303,16 @@
|
||||||
"1": {
|
"1": {
|
||||||
"options": {
|
"options": {
|
||||||
"0": {
|
"0": {
|
||||||
"question": "Drempes met of zonder"
|
"question": "Stoepranden met of zonder voelbare bestrating"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"question": "Stoeprand met voelbare bestrating"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"question": "Stoeprand zonder voelbare bestrating"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"question": "Stoeprand zonder informatie over voelbare bestrating"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4303,6 +4351,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Hoe hoog is deze stoeprand?"
|
"question": "Hoe hoog is deze stoeprand?"
|
||||||
|
},
|
||||||
|
"tactile-paving": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Deze stoeprand heeft voelbare bestrating."
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Deze stoeprand heeft geen voelbare bestrating."
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Deze stoeprand heeft voelbare bestrating, maar deze is incorrect."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Is er voelbare bestrating bij deze stoeprand?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -4353,6 +4415,10 @@
|
||||||
"override": {
|
"override": {
|
||||||
"question": "Wanneer is deze kinderopvang geopend?"
|
"question": "Wanneer is deze kinderopvang geopend?"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"question": "Wat is de naam van deze faciliteit?",
|
||||||
|
"render": "Deze faciliteit heet <b>{name}</b>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -4423,7 +4489,7 @@
|
||||||
"then": "Dit is een woonerf en heeft dus een maximale snelheid van 20km/h"
|
"then": "Dit is een woonerf en heeft dus een maximale snelheid van 20km/h"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"render": "De maximum toegestane snelheid op deze weg is {maxspeed}"
|
"render": "De maximum toegestane snelheid op deze weg is {canonical(maxspeed)}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
@ -6800,5 +6866,92 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"maproulette": {
|
||||||
|
"filter": {
|
||||||
|
"0": {
|
||||||
|
"options": {
|
||||||
|
"1": {
|
||||||
|
"question": "Toon aangemaakte taken"
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"question": "Toon uitgeschakelde taken"
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"question": "Toon taken met alle statussen"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"question": "Toon vals-positieve taken"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"question": "Toon overgeslagen taken"
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"question": "Toon verwijderde taken"
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"question": "Toon al opgeloste taken"
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"question": "Toon taken die als te lastig gemarkeerd zijn"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"question": "Toon opgeloste taken"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"options": {
|
||||||
|
"0": {
|
||||||
|
"question": "Naam uitdaging bevat {search}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"options": {
|
||||||
|
"0": {
|
||||||
|
"question": "ID uitdaging is {search}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Laag met alle taken uit MapRoulette",
|
||||||
|
"name": "MapRoulette Taken"
|
||||||
|
},
|
||||||
|
"transit_routes": {
|
||||||
|
"tagRenderings": {
|
||||||
|
"operator": {
|
||||||
|
"question": "Welk bedrijf exploiteert deze buslijn?",
|
||||||
|
"render": "Deze buslijn wordt geëxploiteerd door {operator}"
|
||||||
|
},
|
||||||
|
"from": {
|
||||||
|
"render": "Deze buslijn begint bij {from}",
|
||||||
|
"question": "Wat is het beginpunt van deze buslijn?"
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"render": "Deze buslijn eindigt bij {to}",
|
||||||
|
"question": "Wat is het eindpunt van deze buslijn?"
|
||||||
|
},
|
||||||
|
"colour": {
|
||||||
|
"question": "Wat is de kleur van deze buslijn?",
|
||||||
|
"render": "Deze buslijn heeft de kleur {colour}"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"question": "Wat is de naam van deze buslijn (bv. Bus XX: Van => Via => Naar)"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"question": "Bij welk netwerk hoort deze buslijn?",
|
||||||
|
"render": "Deze buslijn is onderdeel van het {network} netwerk"
|
||||||
|
},
|
||||||
|
"via": {
|
||||||
|
"question": "Via welk punt gaat deze buslijn?",
|
||||||
|
"render": "Deze buslijn gaat via {via}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"render": "Buslijn"
|
||||||
|
},
|
||||||
|
"description": "Laag met buslijnen",
|
||||||
|
"name": "Buslijnen"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
"readMessages": "Je hebt ongelezen berichten. Je moet deze lezen voordat je een punt verwijderd, een andere bijdrager heeft misschien feedback",
|
"readMessages": "Je hebt ongelezen berichten. Je moet deze lezen voordat je een punt verwijderd, een andere bijdrager heeft misschien feedback",
|
||||||
"reasons": {
|
"reasons": {
|
||||||
"disused": "Het wordt niet meer onderhouden of is verwijderd",
|
"disused": "Het wordt niet meer onderhouden of is verwijderd",
|
||||||
"duplicate": "Dit punt is een duplicaat van een ander punt",
|
"duplicate": "Dit object is een duplicaat van een ander object",
|
||||||
"notFound": "Het kon niet gevonden worden",
|
"notFound": "Het kon niet gevonden worden",
|
||||||
"test": "Dit punt was een test en was nooit echt aanwezig"
|
"test": "Dit punt was een test en was nooit echt aanwezig"
|
||||||
},
|
},
|
||||||
|
@ -49,19 +49,19 @@
|
||||||
"confirmIntro": "<h3>Voeg een {title} toe?</h3>Het punt dat je toevoegt, is <b>zichtbaar voor iedereen</b>. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.",
|
"confirmIntro": "<h3>Voeg een {title} toe?</h3>Het punt dat je toevoegt, is <b>zichtbaar voor iedereen</b>. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.",
|
||||||
"disableFilters": "Zet alle filters af",
|
"disableFilters": "Zet alle filters af",
|
||||||
"disableFiltersExplanation": "Interessepunten kunnen verborgen zijn door een filter",
|
"disableFiltersExplanation": "Interessepunten kunnen verborgen zijn door een filter",
|
||||||
"hasBeenImported": "Dit object is reeds geimporteerd",
|
"hasBeenImported": "Dit object is reeds geïmporteerd",
|
||||||
"import": {
|
"import": {
|
||||||
"hasBeenImported": "Dit object is geïmporteerd",
|
"hasBeenImported": "Dit object is geïmporteerd",
|
||||||
"howToTest": "Voor testmode, voeg <b>test=true</b> of <b>backend=osm-test</b> to aan de URL. De wijzigingenset zal in de console geprint worden. Gelieve een PR te openen om dit thema als officieel thema toe te voegen en zo de import-knop te activeren.",
|
"howToTest": "Voor testmode, voeg <b>test=true</b> of <b>backend=osm-test</b> to aan de URL. De wijzigingenset zal in de console geprint worden. Gelieve een PR te openen om dit thema als officieel thema toe te voegen en zo de import-knop te activeren.",
|
||||||
"importTags": "Het element zal deze tags krijgen: {tags}",
|
"importTags": "Het element zal deze tags krijgen: {tags}",
|
||||||
"officialThemesOnly": "In onofficiële thema's is de importeerknop uitgeschakeld om ongelukjes te vermijden",
|
"officialThemesOnly": "In onofficiële thema's is de importeerknop uitgeschakeld om ongelukjes te vermijden",
|
||||||
"wrongType": "Dit object is geen punt of lijn, en kan daarom niet geïmporteerd worden",
|
"wrongType": "Dit object is geen punt of lijn, en kan daarom niet geïmporteerd worden",
|
||||||
"wrongTypeToConflate": "Dit element is geen punt of weg en kan dus niet samengevoegd worden",
|
"wrongTypeToConflate": "Dit object is geen punt of weg en kan dus niet samengevoegd worden",
|
||||||
"zoomInMore": "Zoom verder in om dit object af te handelen"
|
"zoomInMore": "Zoom verder in om dit object af te handelen"
|
||||||
},
|
},
|
||||||
"importTags": "Het object zal deze tags krijgen: {tags}",
|
"importTags": "Het object zal deze tags krijgen: {tags}",
|
||||||
"intro": "Kies hieronder welk punt je wilt toevoegen<br/>",
|
"intro": "Kies hieronder welk punt je wilt toevoegen<br/>",
|
||||||
"layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een punt toe te voegen",
|
"layerNotEnabled": "De laag {layer} is gedeactiveerd. Activeer deze om een object toe te voegen",
|
||||||
"openLayerControl": "Open de laag-instellingen",
|
"openLayerControl": "Open de laag-instellingen",
|
||||||
"pleaseLogin": "Gelieve je aan te melden om een punt toe te voegen",
|
"pleaseLogin": "Gelieve je aan te melden om een punt toe te voegen",
|
||||||
"presetInfo": "Het nieuwe object krijgt de attributen {tags}",
|
"presetInfo": "Het nieuwe object krijgt de attributen {tags}",
|
||||||
|
@ -272,7 +272,8 @@
|
||||||
"died": "Gestorven: {value}"
|
"died": "Gestorven: {value}"
|
||||||
},
|
},
|
||||||
"searchWikidata": "Zoek op Wikidata",
|
"searchWikidata": "Zoek op Wikidata",
|
||||||
"wikipediaboxTitle": "Wikipedia"
|
"wikipediaboxTitle": "Wikipedia",
|
||||||
|
"searchToShort": "Je zoekopdracht is te kort, vul een langere tekst in"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"image": {
|
"image": {
|
||||||
|
@ -578,7 +579,8 @@
|
||||||
"noNearOrIn": "Sorry, Ik begreep je opdracht niet omdat ik geen <code>dichtbij</code> of <code>in</code> in je zoekopdracht.\nProbeer iets als <code>Zoek drinkwater in Londen</code>, <code>Zoek frituur in Brussel</code><p></p>\n <p>Daarnaast kan je ook <code>info {cmd}</code> proberen, om info te krijgen over een enkel object.</p>",
|
"noNearOrIn": "Sorry, Ik begreep je opdracht niet omdat ik geen <code>dichtbij</code> of <code>in</code> in je zoekopdracht.\nProbeer iets als <code>Zoek drinkwater in Londen</code>, <code>Zoek frituur in Brussel</code><p></p>\n <p>Daarnaast kan je ook <code>info {cmd}</code> proberen, om info te krijgen over een enkel object.</p>",
|
||||||
"nothingFound": "Sorry, ik kon niets vinden voor <code>{search}</code>, dus kan ik {layerTitle} niet zoeken",
|
"nothingFound": "Sorry, ik kon niets vinden voor <code>{search}</code>, dus kan ik {layerTitle} niet zoeken",
|
||||||
"overview": "Ik heb {length} overeenkomende items gevonden.",
|
"overview": "Ik heb {length} overeenkomende items gevonden.",
|
||||||
"searching": "Aan het zoeken naar {layerTitle} {mode} <code>{search}</code>…"
|
"searching": "Aan het zoeken naar {layerTitle} {mode} <code>{search}</code>…",
|
||||||
|
"docs": "Zoekt voor POIs in of nabij een locatie"
|
||||||
},
|
},
|
||||||
"shutdown": {
|
"shutdown": {
|
||||||
"argmode": "Geeft aan op welke manier ik moet afsluiten. Dit moet één van de volgende woorden zijn: {verbs}",
|
"argmode": "Geeft aan op welke manier ik moet afsluiten. Dit moet één van de volgende woorden zijn: {verbs}",
|
||||||
|
|
|
@ -34,6 +34,47 @@
|
||||||
},
|
},
|
||||||
"question": "Does this place have an audio induction loop for people with reduced hearing?"
|
"question": "Does this place have an audio induction loop for people with reduced hearing?"
|
||||||
},
|
},
|
||||||
|
"internet": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "This place offers wireless internet access"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "This place <b>does not</b> offer internet access"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "This place offers internet access"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"then": "This place offers internet access via a terminal or computer"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"then": "This place offers wired internet access"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Does this place offer internet access?"
|
||||||
|
},
|
||||||
|
"internet-fee": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "There is a fee for the internet access at this place"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Internet access is free at this place"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Internet access is free at this place, for customers only"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Is there a fee for internet access?"
|
||||||
|
},
|
||||||
|
"internet-ssid": {
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Enter the network name"
|
||||||
|
},
|
||||||
|
"question": "What is the network name for the wireless internet access?",
|
||||||
|
"render": "The network name is <b>{internet_access:ssid}</b>"
|
||||||
|
},
|
||||||
"level": {
|
"level": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"0": {
|
"0": {
|
||||||
|
|
|
@ -23,6 +23,47 @@
|
||||||
"email": {
|
"email": {
|
||||||
"question": "Wat is het e-mailadres van {title()}?"
|
"question": "Wat is het e-mailadres van {title()}?"
|
||||||
},
|
},
|
||||||
|
"internet": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Deze plaats biedt draadloze internettoegang aan"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Deze plaats biedt <b>geen</b> internettoegang aan"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Deze plaats biedt internettoegang aan"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"then": "Deze plaats biedt internettoegang via een terminal of computer aan"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"then": "Deze plaats biedt bedrade internettoegang aan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Biedt deze plaats internettoegang aan?"
|
||||||
|
},
|
||||||
|
"internet-fee": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Er zijn kosten voor internettoegang op deze plaats"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Internettoegang is gratis op deze plaats"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Internettoegang is gratis op deze plaats, alleen voor klanten"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"question": "Zijn er kosten voor internettoegang?"
|
||||||
|
},
|
||||||
|
"internet-ssid": {
|
||||||
|
"freeform": {
|
||||||
|
"placeholder": "Voer de netwerknaam in"
|
||||||
|
},
|
||||||
|
"question": "Wat is de netwerknaam voor de draadloze internettoegang?",
|
||||||
|
"render": "De netwerknaam is <b>{internet_access:ssid}</b>"
|
||||||
|
},
|
||||||
"level": {
|
"level": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"0": {
|
"0": {
|
||||||
|
|
|
@ -906,6 +906,28 @@
|
||||||
"tagRenderings": {
|
"tagRenderings": {
|
||||||
"streetname": {
|
"streetname": {
|
||||||
"render": "Diese Straße heißt {name}"
|
"render": "Diese Straße heißt {name}"
|
||||||
|
},
|
||||||
|
"left-right-questions": {
|
||||||
|
"renderings": {
|
||||||
|
"1": {
|
||||||
|
"question": "Gibt es auf dieser Straßenseite einen Bürgersteig?",
|
||||||
|
"mappings": {
|
||||||
|
"1": {
|
||||||
|
"then": "Nein, es gibt keinen Bürgersteig für Fußgänger"
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"then": "Ja, es gibt einen Bürgersteig auf dieser Straßenseite"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Es gibt einen separat kartierten Bürgersteig für Fußgänger"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"question": "Wie breit ist der Bürgersteig auf dieser Straßenseite?",
|
||||||
|
"render": "Dieser Bürgersteig ist {sidewalk:left|right:width}m breit"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"cannotBeDeleted": "這圖徵無法刪除",
|
"cannotBeDeleted": "這圖徵無法刪除",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"explanations": {
|
"explanations": {
|
||||||
"hardDelete": "這個點已經在開放街圖被刪除了,可以被實驗性的貢獻者恢復",
|
"hardDelete": "這個圖徵已經在開放街圖被刪除了,可以被實驗性的貢獻者恢復",
|
||||||
"selectReason": "請選擇為什麼這個圖徵應該被刪除",
|
"selectReason": "請選擇為什麼這個圖徵應該被刪除",
|
||||||
"softDelete": "這個圖徵已經被更新,然後從程式被隱藏了。<span class=\"subtle\">{reason}</span>"
|
"softDelete": "這個圖徵已經被更新,然後從程式被隱藏了。<span class=\"subtle\">{reason}</span>"
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,22 +7,21 @@ describe("Unit", () => {
|
||||||
|
|
||||||
it("should convert a value back and forth", () => {
|
it("should convert a value back and forth", () => {
|
||||||
|
|
||||||
const unit = new Denomination({
|
const denomintion = new Denomination({
|
||||||
"canonicalDenomination": "MW",
|
"canonicalDenomination": "MW",
|
||||||
"alternativeDenomination": ["megawatts", "megawatt"],
|
"alternativeDenomination": ["megawatts", "megawatt"],
|
||||||
"human": {
|
"human": {
|
||||||
"en": " megawatts",
|
"en": " megawatts",
|
||||||
"nl": " megawatt"
|
"nl": " megawatt"
|
||||||
},
|
},
|
||||||
"default": true
|
|
||||||
}, "test");
|
}, "test");
|
||||||
|
|
||||||
const canonical = unit.canonicalValue("5")
|
const canonical = denomintion.canonicalValue("5", true)
|
||||||
expect(canonical).eq( "5 MW")
|
expect(canonical).eq( "5 MW")
|
||||||
const units = new Unit(["key"], [unit], false)
|
const units = new Unit(["key"], [denomintion], false)
|
||||||
const [detected, detectedDenom] = units.findDenomination("5 MW")
|
const [detected, detectedDenom] = units.findDenomination("5 MW", () => "be")
|
||||||
expect(detected).eq( "5")
|
expect(detected).eq( "5")
|
||||||
expect(detectedDenom).eq( unit)
|
expect(detectedDenom).eq( denomintion)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|