Move 'defaultInputUnit' into Unit, away from denomination
This commit is contained in:
parent
03057b2eff
commit
67b5a33f0b
9 changed files with 135 additions and 84 deletions
|
@ -15,7 +15,7 @@ export class Denomination {
|
||||||
private readonly _human: Translation
|
private readonly _human: Translation
|
||||||
private readonly _humanSingular?: Translation
|
private readonly _humanSingular?: Translation
|
||||||
|
|
||||||
constructor(json: DenominationConfigJson, context: string) {
|
constructor(json: DenominationConfigJson, useAsDefaultInput: boolean, 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) {
|
||||||
|
@ -35,7 +35,7 @@ export class Denomination {
|
||||||
throw `${context} uses the old 'default'-key. Use "useIfNoUnitGiven" or "useAsDefaultInput" instead`
|
throw `${context} uses the old 'default'-key. Use "useIfNoUnitGiven" or "useAsDefaultInput" instead`
|
||||||
}
|
}
|
||||||
this.useIfNoUnitGiven = json.useIfNoUnitGiven
|
this.useIfNoUnitGiven = json.useIfNoUnitGiven
|
||||||
this.useAsDefaultInput = json.useAsDefaultInput ?? json.useIfNoUnitGiven
|
this.useAsDefaultInput = 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")
|
||||||
|
@ -69,7 +69,7 @@ export class Denomination {
|
||||||
* human: {
|
* human: {
|
||||||
* en: "meter"
|
* en: "meter"
|
||||||
* }
|
* }
|
||||||
* }, "test")
|
* }, false, "test")
|
||||||
* unit.canonicalValue("42m", true) // =>"42 m"
|
* unit.canonicalValue("42m", true) // =>"42 m"
|
||||||
* unit.canonicalValue("42", true) // =>"42 m"
|
* unit.canonicalValue("42", true) // =>"42 m"
|
||||||
* unit.canonicalValue("42 m", true) // =>"42 m"
|
* unit.canonicalValue("42 m", true) // =>"42 m"
|
||||||
|
@ -84,7 +84,7 @@ export class Denomination {
|
||||||
* human: {
|
* human: {
|
||||||
* en: "meter"
|
* en: "meter"
|
||||||
* }
|
* }
|
||||||
* }, "test")
|
* }, false, "test")
|
||||||
* unit.canonicalValue("42m", true) // =>"42"
|
* unit.canonicalValue("42m", true) // =>"42"
|
||||||
* unit.canonicalValue("42", true) // =>"42"
|
* unit.canonicalValue("42", true) // =>"42"
|
||||||
* unit.canonicalValue("42 m", true) // =>"42"
|
* unit.canonicalValue("42 m", true) // =>"42"
|
||||||
|
|
|
@ -389,62 +389,7 @@ export interface LayerConfigJson {
|
||||||
allowSplit?: boolean
|
allowSplit?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)
|
* @see UnitConfigJson
|
||||||
*
|
|
||||||
* Sometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)
|
|
||||||
*
|
|
||||||
* This brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)
|
|
||||||
*
|
|
||||||
* Not only do we want to write consistent data to OSM, we also want to present this consistently to the user.
|
|
||||||
* This is handled by defining units.
|
|
||||||
*
|
|
||||||
* # Rendering
|
|
||||||
*
|
|
||||||
* To render a value with long (human) denomination, use {canonical(key)}
|
|
||||||
*
|
|
||||||
* # Usage
|
|
||||||
*
|
|
||||||
* First of all, you define which keys have units applied, for example:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* units: [
|
|
||||||
* appliesTo: ["maxspeed", "maxspeed:hgv", "maxspeed:bus"]
|
|
||||||
* applicableUnits: [
|
|
||||||
* ...
|
|
||||||
* ]
|
|
||||||
* ]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* ApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* applicableUnits: [
|
|
||||||
* {
|
|
||||||
* canonicalDenomination: "km/h",
|
|
||||||
* alternativeDenomination: ["km/u", "kmh", "kph"]
|
|
||||||
* default: true,
|
|
||||||
* human: {
|
|
||||||
* en: "kilometer/hour",
|
|
||||||
* nl: "kilometer/uur"
|
|
||||||
* },
|
|
||||||
* humanShort: {
|
|
||||||
* en: "km/h",
|
|
||||||
* nl: "km/u"
|
|
||||||
* }
|
|
||||||
* },
|
|
||||||
* {
|
|
||||||
* canoncialDenomination: "mph",
|
|
||||||
* ... similar for miles an hour ...
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* If this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:
|
|
||||||
* every value will be parsed and the canonical extension will be added add presented to the other parts of the code.
|
|
||||||
*
|
|
||||||
* Also, if a freeform text field is used, an extra dropdown with applicable denominations will be given
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
units?: UnitConfigJson[]
|
units?: UnitConfigJson[]
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,61 @@
|
||||||
|
/**
|
||||||
|
* In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)
|
||||||
|
*
|
||||||
|
* Sometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)
|
||||||
|
*
|
||||||
|
* This brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)
|
||||||
|
*
|
||||||
|
* Not only do we want to write consistent data to OSM, we also want to present this consistently to the user.
|
||||||
|
* This is handled by defining units.
|
||||||
|
*
|
||||||
|
* # Rendering
|
||||||
|
*
|
||||||
|
* To render a value with long (human) denomination, use {canonical(key)}
|
||||||
|
*
|
||||||
|
* # Usage
|
||||||
|
*
|
||||||
|
* First of all, you define which keys have units applied, for example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* units: [
|
||||||
|
* appliesTo: ["maxspeed", "maxspeed:hgv", "maxspeed:bus"]
|
||||||
|
* applicableUnits: [
|
||||||
|
* ...
|
||||||
|
* ]
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* applicableUnits: [
|
||||||
|
* {
|
||||||
|
* canonicalDenomination: "km/h",
|
||||||
|
* alternativeDenomination: ["km/u", "kmh", "kph"]
|
||||||
|
* default: true,
|
||||||
|
* human: {
|
||||||
|
* en: "kilometer/hour",
|
||||||
|
* nl: "kilometer/uur"
|
||||||
|
* },
|
||||||
|
* humanShort: {
|
||||||
|
* en: "km/h",
|
||||||
|
* nl: "km/u"
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* canoncialDenomination: "mph",
|
||||||
|
* ... similar for miles an hour ...
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* If this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:
|
||||||
|
* every value will be parsed and the canonical extension will be added add presented to the other parts of the code.
|
||||||
|
*
|
||||||
|
* Also, if a freeform text field is used, an extra dropdown with applicable denominations will be given
|
||||||
|
*
|
||||||
|
*/
|
||||||
export default interface UnitConfigJson {
|
export default interface UnitConfigJson {
|
||||||
/**
|
/**
|
||||||
* Every key from this list will be normalized.
|
* Every key from this list will be normalized.
|
||||||
|
@ -11,9 +69,19 @@ export default interface UnitConfigJson {
|
||||||
*/
|
*/
|
||||||
eraseInvalidValues?: boolean
|
eraseInvalidValues?: boolean
|
||||||
/**
|
/**
|
||||||
* The possible denominations
|
* The possible denominations for this unit.
|
||||||
|
* For length, denominations could be "meter", "kilometer", "miles", "foot"
|
||||||
*/
|
*/
|
||||||
applicableUnits: DenominationConfigJson[]
|
applicableUnits: DenominationConfigJson[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In some cases, the default denomination is not the most user friendly to input.
|
||||||
|
* E.g., when measuring kerb heights, it is illogical to ask contributors to input an amount in meters.
|
||||||
|
*
|
||||||
|
* When a default input method should be used, this can be specified by setting the canonical denomination here, e.g.
|
||||||
|
* `defaultInput: "cm"`. This must be a denomination which appears in the applicableUnits
|
||||||
|
*/
|
||||||
|
defaultInput?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DenominationConfigJson {
|
export interface DenominationConfigJson {
|
||||||
|
@ -28,12 +96,6 @@ export interface DenominationConfigJson {
|
||||||
*/
|
*/
|
||||||
useIfNoUnitGiven?: boolean | string[]
|
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.
|
* 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
|
||||||
|
@ -46,12 +108,15 @@ export interface DenominationConfigJson {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* Used for display purposes only.
|
||||||
|
*
|
||||||
|
* E.g.: for duration of something in minutes: `2 minutes` but `1 minute`; the `minute` goes here
|
||||||
*/
|
*/
|
||||||
canonicalDenominationSingular?: string
|
canonicalDenominationSingular?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of alternative values which can occur in the OSM database - used for parsing.
|
* A list of alternative values which can occur in the OSM database - used for parsing.
|
||||||
|
* E.g.: while 'm' is canonical, `meter`, `mtrs`, ... can occur as well
|
||||||
*/
|
*/
|
||||||
alternativeDenomination?: string[]
|
alternativeDenomination?: string[]
|
||||||
|
|
||||||
|
@ -62,16 +127,16 @@ export interface DenominationConfigJson {
|
||||||
* "fr": "metre"
|
* "fr": "metre"
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
human?: string | any
|
human?: string | Record<string, string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.
|
* The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.
|
||||||
* {
|
* {
|
||||||
* "en": "minute",
|
* "en": "minute",
|
||||||
* "nl": "minuut"x²
|
* "nl": "minuut"
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
humanSingular?: string | any
|
humanSingular?: string | Record<string, string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set, then the canonical value will be prefixed instead, e.g. for '€'
|
* If set, then the canonical value will be prefixed instead, e.g. for '€'
|
||||||
|
|
|
@ -60,6 +60,44 @@ export class Unit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* // Should detect invalid defaultInput
|
||||||
|
* let threwError = false
|
||||||
|
* try{
|
||||||
|
* Unit.fromJson({
|
||||||
|
* appliesToKey: ["length"],
|
||||||
|
* defaultInput: "xcm",
|
||||||
|
* applicableUnits: [
|
||||||
|
* {
|
||||||
|
* canonicalDenomination: "m",
|
||||||
|
* useIfNoUnitGiven: true,
|
||||||
|
* human: "meter"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* },"test")
|
||||||
|
* }catch(e){
|
||||||
|
* threwError =true
|
||||||
|
* }
|
||||||
|
* threwError // => false
|
||||||
|
*
|
||||||
|
* // Should work
|
||||||
|
* Unit.fromJson({
|
||||||
|
* appliesToKey: ["length"],
|
||||||
|
* defaultInput: "xcm",
|
||||||
|
* applicableUnits: [
|
||||||
|
* {
|
||||||
|
* canonicalDenomination: "m",
|
||||||
|
* useIfNoUnitGiven: true,
|
||||||
|
* humen: "meter"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* canonicalDenomination: "cm",
|
||||||
|
* human: "centimeter"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }, "test")
|
||||||
|
*/
|
||||||
static fromJson(json: UnitConfigJson, ctx: string) {
|
static fromJson(json: UnitConfigJson, ctx: string) {
|
||||||
const appliesTo = json.appliesToKey
|
const appliesTo = json.appliesToKey
|
||||||
for (let i = 0; i < appliesTo.length; i++) {
|
for (let i = 0; i < appliesTo.length; i++) {
|
||||||
|
@ -74,14 +112,13 @@ export class Unit {
|
||||||
}
|
}
|
||||||
// Some keys do have unit handling
|
// Some keys do have unit handling
|
||||||
|
|
||||||
if (json.applicableUnits.some((denom) => denom.useAsDefaultInput !== undefined)) {
|
|
||||||
json.applicableUnits.forEach((denom) => {
|
|
||||||
denom.useAsDefaultInput = denom.useAsDefaultInput ?? false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const applicable = json.applicableUnits.map(
|
const applicable = json.applicableUnits.map(
|
||||||
(u, i) => new Denomination(u, `${ctx}.units[${i}]`)
|
(u, i) =>
|
||||||
|
new Denomination(
|
||||||
|
u,
|
||||||
|
u.canonicalDenomination.trim() === json.defaultInput,
|
||||||
|
`${ctx}.units[${i}]`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return new Unit(appliesTo, applicable, json.eraseInvalidValues ?? false)
|
return new Unit(appliesTo, applicable, json.eraseInvalidValues ?? false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,6 +205,7 @@
|
||||||
"elevator:width",
|
"elevator:width",
|
||||||
"elevator:depth"
|
"elevator:depth"
|
||||||
],
|
],
|
||||||
|
"defaultInput": "cm",
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
"canonicalDenomination": "m",
|
"canonicalDenomination": "m",
|
||||||
|
@ -221,7 +222,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"useAsDefaultInput": true,
|
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
@ -238,4 +238,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,6 +473,7 @@
|
||||||
"kerb:height",
|
"kerb:height",
|
||||||
"width"
|
"width"
|
||||||
],
|
],
|
||||||
|
"defaultInput": "cm",
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
"useIfNoUnitGiven": true,
|
"useIfNoUnitGiven": true,
|
||||||
|
@ -489,7 +490,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"useAsDefaultInput": true,
|
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
@ -506,4 +506,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
3
assets/layers/units/units.json
Normal file
3
assets/layers/units/units.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -63,6 +63,7 @@
|
||||||
"width",
|
"width",
|
||||||
"_biggest_width"
|
"_biggest_width"
|
||||||
],
|
],
|
||||||
|
"defaultUnit": "cm",
|
||||||
"applicableUnits": [
|
"applicableUnits": [
|
||||||
{
|
{
|
||||||
"useIfNoUnitGiven": true,
|
"useIfNoUnitGiven": true,
|
||||||
|
@ -79,7 +80,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"useAsDefaultInput": true,
|
|
||||||
"canonicalDenomination": "cm",
|
"canonicalDenomination": "cm",
|
||||||
"alternativeDenomination": [
|
"alternativeDenomination": [
|
||||||
"centimeter",
|
"centimeter",
|
||||||
|
@ -150,4 +150,4 @@
|
||||||
"condition": "_biggest_width_id~*"
|
"condition": "_biggest_width_id~*"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ describe("Unit", () => {
|
||||||
nl: " megawatt",
|
nl: " megawatt",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
false,
|
||||||
"test"
|
"test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue