From 8f036f6045a21c60379c67758caf60d9efe77dc7 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 12 Jan 2024 23:19:31 +0100 Subject: [PATCH] Studio: small improvements after selftesting, icons reusing HeroIcons can now be colored as well --- .../DenominationConfigJson.schema.json | 4 + Docs/Schemas/DenominationConfigJsonJSC.ts | 4 + Docs/Schemas/IconConfigJson.schema.json | 6 +- Docs/Schemas/IconConfigJsonJSC.ts | 6 +- Docs/Schemas/LayerConfigJson.schema.json | 164 +- Docs/Schemas/LayerConfigJsonJSC.ts | 163 +- Docs/Schemas/LayoutConfigJson.schema.json | 193 +- Docs/Schemas/LayoutConfigJsonJSC.ts | 192 +- .../LineRenderingConfigJson.schema.json | 6 +- Docs/Schemas/LineRenderingConfigJsonJSC.ts | 6 +- Docs/Schemas/MappingConfigJson.schema.json | 20 +- Docs/Schemas/MappingConfigJsonJSC.ts | 20 +- Docs/Schemas/MoveConfigJson.schema.json | 4 + Docs/Schemas/MoveConfigJsonJSC.ts | 4 + .../PointRenderingConfigJson.schema.json | 6 +- Docs/Schemas/PointRenderingConfigJsonJSC.ts | 6 +- ...tionableTagRenderingConfigJson.schema.json | 31 +- .../QuestionableTagRenderingConfigJsonJSC.ts | 31 +- Docs/Schemas/RewritableConfigJson.schema.json | 35 +- Docs/Schemas/RewritableConfigJsonJSC.ts | 35 +- Docs/Schemas/UnitConfigJson.schema.json | 11 +- Docs/Schemas/UnitConfigJsonJSC.ts | 11 +- public/css/index-tailwind-output.css | 54 +- scripts/fixSchemas.ts | 4 +- src/Models/Constants.ts | 35 +- .../ThemeConfig/Conversion/Validation.ts | 33 +- .../ThemeConfig/Json/LayerConfigJson.ts | 2 +- .../Json/PointRenderingConfigJson.ts | 2 +- .../ThemeConfig/PointRenderingConfig.ts | 16 - src/Models/ThemeConfig/TagRenderingConfig.ts | 15 +- .../OpenBackgroundSelectorButton.svelte | 2 +- src/UI/Map/DynamicIcon.svelte | 2 +- src/UI/Map/Icon.svelte | 86 +- .../TagRendering/TagRenderingEditable.svelte | 2 +- .../TagRendering/TagRenderingQuestion.svelte | 2 +- src/UI/Studio/ArrayMultiAnswer.svelte | 1 - src/UI/Studio/QuestionPreview.svelte | 1 - src/UI/Studio/SchemaBasedField.svelte | 1 - src/UI/Studio/SchemaBasedMultiType.svelte | 1 - src/UI/Studio/TagRenderingInput.svelte | 1 - src/UI/Test.svelte | 13 +- src/assets/schemas/layerconfigmeta.json | 3181 +++++++- src/assets/schemas/layoutconfigmeta.json | 6721 ++++++++++++++++- .../questionabletagrenderingconfigmeta.json | 108 + src/index.css | 7 + 45 files changed, 10960 insertions(+), 288 deletions(-) diff --git a/Docs/Schemas/DenominationConfigJson.schema.json b/Docs/Schemas/DenominationConfigJson.schema.json index a5086168f..0e7029321 100644 --- a/Docs/Schemas/DenominationConfigJson.schema.json +++ b/Docs/Schemas/DenominationConfigJson.schema.json @@ -121,6 +121,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/DenominationConfigJsonJSC.ts b/Docs/Schemas/DenominationConfigJsonJSC.ts index acc2c079f..bcd5c37ea 100644 --- a/Docs/Schemas/DenominationConfigJsonJSC.ts +++ b/Docs/Schemas/DenominationConfigJsonJSC.ts @@ -117,6 +117,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/IconConfigJson.schema.json b/Docs/Schemas/IconConfigJson.schema.json index 6c637ccf8..249398bcb 100644 --- a/Docs/Schemas/IconConfigJson.schema.json +++ b/Docs/Schemas/IconConfigJson.schema.json @@ -2,7 +2,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -174,6 +174,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/IconConfigJsonJSC.ts b/Docs/Schemas/IconConfigJsonJSC.ts index eaf84c900..211310552 100644 --- a/Docs/Schemas/IconConfigJsonJSC.ts +++ b/Docs/Schemas/IconConfigJsonJSC.ts @@ -2,7 +2,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -170,6 +170,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/LayerConfigJson.schema.json b/Docs/Schemas/LayerConfigJson.schema.json index 9a422409f..71c271581 100644 --- a/Docs/Schemas/LayerConfigJson.schema.json +++ b/Docs/Schemas/LayerConfigJson.schema.json @@ -85,7 +85,7 @@ ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -136,14 +136,26 @@ "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -253,7 +265,7 @@ } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -370,7 +382,14 @@ "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { @@ -518,6 +537,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -561,7 +584,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -850,6 +873,20 @@ } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -1242,6 +1279,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1457,6 +1505,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1597,33 +1656,71 @@ "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" }, - "override": { - "$ref": "#/definitions/Partial" + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" } - }, - "required": [ - "builtin", - "override" ] - }, - { - "type": "string" } - ] - } + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + } + ] } }, "required": [ @@ -1784,6 +1881,10 @@ "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -1808,10 +1909,13 @@ } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ], "additionalProperties": false + }, + "Record": { + "type": "object", + "additionalProperties": false } }, "$schema": "http://json-schema.org/draft-07/schema#", diff --git a/Docs/Schemas/LayerConfigJsonJSC.ts b/Docs/Schemas/LayerConfigJsonJSC.ts index 95913b742..61102e21e 100644 --- a/Docs/Schemas/LayerConfigJsonJSC.ts +++ b/Docs/Schemas/LayerConfigJsonJSC.ts @@ -85,7 +85,7 @@ export default { ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -136,14 +136,26 @@ export default { "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -253,7 +265,7 @@ export default { } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -370,7 +382,14 @@ export default { "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { @@ -514,6 +533,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -555,7 +578,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -841,6 +864,20 @@ export default { } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -1229,6 +1266,17 @@ export default { } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1443,6 +1491,17 @@ export default { } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1582,33 +1641,71 @@ export default { "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" }, - "override": { - "$ref": "#/definitions/Partial" + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" } - }, - "required": [ - "builtin", - "override" ] - }, - { - "type": "string" } - ] - } + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + } + ] } }, "required": [ @@ -1765,6 +1862,10 @@ export default { "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -1789,9 +1890,11 @@ export default { } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ] + }, + "Record": { + "type": "object" } }, "$schema": "http://json-schema.org/draft-07/schema#" diff --git a/Docs/Schemas/LayoutConfigJson.schema.json b/Docs/Schemas/LayoutConfigJson.schema.json index bfd4fb447..f3a5ee161 100644 --- a/Docs/Schemas/LayoutConfigJson.schema.json +++ b/Docs/Schemas/LayoutConfigJson.schema.json @@ -427,6 +427,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -470,7 +474,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -759,6 +763,20 @@ } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -1151,6 +1169,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1366,6 +1395,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1506,33 +1546,71 @@ "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" }, - "override": { - "$ref": "#/definitions/Partial" + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" } - }, - "required": [ - "builtin", - "override" ] - }, - { - "type": "string" } - ] - } + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + } + ] } }, "required": [ @@ -1693,6 +1771,10 @@ "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -1717,11 +1799,14 @@ } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ], "additionalProperties": false }, + "Record": { + "type": "object", + "additionalProperties": false + }, "default": { "type": "object", "properties": { @@ -1854,7 +1939,7 @@ ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -1905,14 +1990,26 @@ "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -2022,7 +2119,7 @@ } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -2139,7 +2236,14 @@ "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { @@ -2254,7 +2358,7 @@ ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -2305,14 +2409,26 @@ "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -2422,7 +2538,7 @@ } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -2539,7 +2655,14 @@ "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { diff --git a/Docs/Schemas/LayoutConfigJsonJSC.ts b/Docs/Schemas/LayoutConfigJsonJSC.ts index 411c1e6d1..952ff3555 100644 --- a/Docs/Schemas/LayoutConfigJsonJSC.ts +++ b/Docs/Schemas/LayoutConfigJsonJSC.ts @@ -423,6 +423,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -464,7 +468,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -750,6 +754,20 @@ export default { } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -1138,6 +1156,17 @@ export default { } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1352,6 +1381,17 @@ export default { } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1491,33 +1531,71 @@ export default { "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" }, - "override": { - "$ref": "#/definitions/Partial" + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" } - }, - "required": [ - "builtin", - "override" ] - }, - { - "type": "string" } - ] - } + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": { + "$ref": "#/definitions/Partial" + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + } + ] } }, "required": [ @@ -1674,6 +1752,10 @@ export default { "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -1698,10 +1780,12 @@ export default { } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ] }, + "Record": { + "type": "object" + }, "default": { "type": "object", "properties": { @@ -1833,7 +1917,7 @@ export default { ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -1884,14 +1968,26 @@ export default { "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -2001,7 +2097,7 @@ export default { } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -2118,7 +2214,14 @@ export default { "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { @@ -2232,7 +2335,7 @@ export default { ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -2283,14 +2386,26 @@ export default { "type": "boolean" }, "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]\ngroup: infobox", + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nUse `auto:` to automatically create an icon based on a tagRendering which has icons\n\nType: icon[]\ngroup: infobox", "anyOf": [ { "type": "array", "items": { "anyOf": [ { - "$ref": "#/definitions/TagRenderingConfigJson" + "allOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + ] }, { "type": "string" @@ -2400,7 +2515,7 @@ export default { } }, "tagRenderings": { - "description": "question: Edit this attribute showing piece/question\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", + "description": "question: Edit this way this attributed is displayed or queried\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "type": "array", "items": { "anyOf": [ @@ -2517,7 +2632,14 @@ export default { "units": { "type": "array", "items": { - "$ref": "#/definitions/default_2" + "anyOf": [ + { + "$ref": "#/definitions/default_2" + }, + { + "$ref": "#/definitions/Record" + } + ] } }, "syncSelection": { diff --git a/Docs/Schemas/LineRenderingConfigJson.schema.json b/Docs/Schemas/LineRenderingConfigJson.schema.json index a9fe41351..f59108138 100644 --- a/Docs/Schemas/LineRenderingConfigJson.schema.json +++ b/Docs/Schemas/LineRenderingConfigJson.schema.json @@ -186,6 +186,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -229,7 +233,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/LineRenderingConfigJsonJSC.ts b/Docs/Schemas/LineRenderingConfigJsonJSC.ts index f28b3d00c..a19933c43 100644 --- a/Docs/Schemas/LineRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/LineRenderingConfigJsonJSC.ts @@ -182,6 +182,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -223,7 +227,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/MappingConfigJson.schema.json b/Docs/Schemas/MappingConfigJson.schema.json index ee62920a2..fd0711e63 100644 --- a/Docs/Schemas/MappingConfigJson.schema.json +++ b/Docs/Schemas/MappingConfigJson.schema.json @@ -57,6 +57,20 @@ } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -226,6 +240,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -269,7 +287,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/MappingConfigJsonJSC.ts b/Docs/Schemas/MappingConfigJsonJSC.ts index 6aaf9c8ea..5d17ec4af 100644 --- a/Docs/Schemas/MappingConfigJsonJSC.ts +++ b/Docs/Schemas/MappingConfigJsonJSC.ts @@ -57,6 +57,20 @@ export default { } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ @@ -222,6 +236,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -263,7 +281,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/MoveConfigJson.schema.json b/Docs/Schemas/MoveConfigJson.schema.json index 1ef6e876e..25a147127 100644 --- a/Docs/Schemas/MoveConfigJson.schema.json +++ b/Docs/Schemas/MoveConfigJson.schema.json @@ -131,6 +131,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/MoveConfigJsonJSC.ts b/Docs/Schemas/MoveConfigJsonJSC.ts index c25c8d051..f460491dc 100644 --- a/Docs/Schemas/MoveConfigJsonJSC.ts +++ b/Docs/Schemas/MoveConfigJsonJSC.ts @@ -127,6 +127,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/PointRenderingConfigJson.schema.json b/Docs/Schemas/PointRenderingConfigJson.schema.json index 3fb7d5270..133d3c69d 100644 --- a/Docs/Schemas/PointRenderingConfigJson.schema.json +++ b/Docs/Schemas/PointRenderingConfigJson.schema.json @@ -287,6 +287,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -330,7 +334,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/PointRenderingConfigJsonJSC.ts b/Docs/Schemas/PointRenderingConfigJsonJSC.ts index 491729936..8fa653618 100644 --- a/Docs/Schemas/PointRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/PointRenderingConfigJsonJSC.ts @@ -283,6 +283,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -324,7 +328,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" diff --git a/Docs/Schemas/QuestionableTagRenderingConfigJson.schema.json b/Docs/Schemas/QuestionableTagRenderingConfigJson.schema.json index 29e9256c4..b5552e84e 100644 --- a/Docs/Schemas/QuestionableTagRenderingConfigJson.schema.json +++ b/Docs/Schemas/QuestionableTagRenderingConfigJson.schema.json @@ -97,6 +97,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -333,6 +344,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -376,7 +391,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -665,6 +680,20 @@ } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ diff --git a/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts b/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts index e39965956..9628cd0a4 100644 --- a/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts @@ -97,6 +97,17 @@ export default { } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -329,6 +340,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -370,7 +385,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -656,6 +671,20 @@ export default { } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ diff --git a/Docs/Schemas/RewritableConfigJson.schema.json b/Docs/Schemas/RewritableConfigJson.schema.json index 8f00d2fdf..2e8a5be15 100644 --- a/Docs/Schemas/RewritableConfigJson.schema.json +++ b/Docs/Schemas/RewritableConfigJson.schema.json @@ -24,8 +24,21 @@ "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "$ref": "#/definitions/T" + "anyOf": [ + { + "$ref": "#/definitions/T" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/T" + } + } + ] } }, "required": [ @@ -153,6 +166,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -196,7 +213,7 @@ "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -485,6 +502,20 @@ } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ diff --git a/Docs/Schemas/RewritableConfigJsonJSC.ts b/Docs/Schemas/RewritableConfigJsonJSC.ts index df90f44f1..543e15791 100644 --- a/Docs/Schemas/RewritableConfigJsonJSC.ts +++ b/Docs/Schemas/RewritableConfigJsonJSC.ts @@ -24,8 +24,21 @@ export default { "sourceString" ] }, + "subexpand": { + "$ref": "#/definitions/Record" + }, "renderings": { - "$ref": "#/definitions/T" + "anyOf": [ + { + "$ref": "#/definitions/T" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/T" + } + } + ] } }, "required": [ @@ -149,6 +162,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ @@ -190,7 +207,7 @@ export default { "type": "object", "properties": { "icon": { - "description": "question: What icon should be used?\ntype: icon\nsuggestions: return [\"pin\",\"square\",\"circle\",\"checkmark\",\"clock\",\"close\",\"crosshair\",\"help\",\"home\",\"invalid\",\"location\",\"location_empty\",\"location_locked\",\"note\",\"resolved\",\"ring\",\"scissors\",\"teardrop\",\"teardrop_with_hole_green\",\"triangle\"].map(i => ({if: \"value=\"+i, then: i, icon: i}))", + "description": "question: What icon should be used?\ntype: icon\nsuggestions: return Constants.defaultPinIcons.map(i => ({if: \"value=\"+i, then: i, icon: i}))", "anyOf": [ { "$ref": "#/definitions/MinimalTagRenderingConfigJson" @@ -476,6 +493,20 @@ export default { } ] }, + "alsoShowIf": { + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags.", + "anyOf": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ] + }, "ifnot": { "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.", "anyOf": [ diff --git a/Docs/Schemas/UnitConfigJson.schema.json b/Docs/Schemas/UnitConfigJson.schema.json index 252f208de..7042ee043 100644 --- a/Docs/Schemas/UnitConfigJson.schema.json +++ b/Docs/Schemas/UnitConfigJson.schema.json @@ -2,6 +2,10 @@ "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -26,8 +30,7 @@ } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ], "definitions": { "TagConfigJson": { @@ -150,6 +153,10 @@ "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/Docs/Schemas/UnitConfigJsonJSC.ts b/Docs/Schemas/UnitConfigJsonJSC.ts index b8d7b913b..3ea0ef4a5 100644 --- a/Docs/Schemas/UnitConfigJsonJSC.ts +++ b/Docs/Schemas/UnitConfigJsonJSC.ts @@ -2,6 +2,10 @@ export default { "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", "type": "object", "properties": { + "quantity": { + "description": "What is quantified? E.g. 'speed', 'length' (including width, diameter, ...), 'electric tension', 'electric current', 'duration'", + "type": "string" + }, "appliesToKey": { "description": "Every key from this list will be normalized.\n\nTo render the value properly (with a human readable denomination), use `{canonical()}`", "type": "array", @@ -26,8 +30,7 @@ export default { } }, "required": [ - "applicableUnits", - "appliesToKey" + "applicableUnits" ], "definitions": { "TagConfigJson": { @@ -146,6 +149,10 @@ export default { "prefix": { "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", "type": "boolean" + }, + "addSpace": { + "description": "If set, add a space between the quantity and the denomination.\n\nE.g.: `50 mph` instad of `50mph`", + "type": "boolean" } }, "required": [ diff --git a/public/css/index-tailwind-output.css b/public/css/index-tailwind-output.css index 50cced769..bb24d6daa 100644 --- a/public/css/index-tailwind-output.css +++ b/public/css/index-tailwind-output.css @@ -777,6 +777,10 @@ video { float: left; } +.m-8 { + margin: 2rem; +} + .m-4 { margin: 1rem; } @@ -789,10 +793,6 @@ video { margin: 0px; } -.m-8 { - margin: 2rem; -} - .m-2 { margin: 0.5rem; } @@ -1071,14 +1071,14 @@ video { height: 6rem; } -.h-screen { - height: 100vh; -} - .h-full { height: 100%; } +.h-screen { + height: 100vh; +} + .h-32 { height: 8rem; } @@ -1106,6 +1106,10 @@ video { height: fit-content; } +.h-16 { + height: 4rem; +} + .h-0 { height: 0px; } @@ -1134,10 +1138,6 @@ video { height: 1.25rem; } -.h-16 { - height: 4rem; -} - .h-48 { height: 12rem; } @@ -1202,6 +1202,10 @@ video { width: 1.5rem; } +.w-16 { + width: 4rem; +} + .w-screen { width: 100vw; } @@ -1236,10 +1240,6 @@ video { width: 2.75rem; } -.w-16 { - width: 4rem; -} - .w-64 { width: 16rem; } @@ -1931,11 +1931,6 @@ video { line-height: 1.75rem; } -.text-5xl { - font-size: 3rem; - line-height: 1; -} - .text-sm { font-size: 0.875rem; line-height: 1.25rem; @@ -1956,6 +1951,11 @@ video { line-height: 2.5rem; } +.text-5xl { + font-size: 3rem; + line-height: 1; +} + .font-extrabold { font-weight: 800; } @@ -2039,11 +2039,6 @@ video { letter-spacing: -0.025em; } -.text-red-500 { - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity)); -} - .text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); @@ -2250,6 +2245,9 @@ video { --catch-detail-foregroundcolor: white; --catch-detail-color-contrast: #fb3afb; --image-carousel-height: 350px; + /** Technical value, used by icon.svelte + */ + --svg-color: #000000; } /***********************************************************************\ @@ -2795,6 +2793,10 @@ a.link-underline { overflow: visible !important; } +svg.apply-fill path { + fill: var(--svg-color) +} + .compass_arrow { width: calc( 2.5rem - 1px ) ; height: calc( 2.5rem - 1px ) diff --git a/scripts/fixSchemas.ts b/scripts/fixSchemas.ts index 3acfec8ee..8d26dc720 100644 --- a/scripts/fixSchemas.ts +++ b/scripts/fixSchemas.ts @@ -6,6 +6,7 @@ import { Utils } from "../src/Utils" import Validators from "../src/UI/InputElement/Validators" import { AllKnownLayouts } from "../src/Customizations/AllKnownLayouts" import { AllSharedLayers } from "../src/Customizations/AllSharedLayers" +import Constants from "../src/Models/Constants" const metainfo = { type: "One of the inputValidator types", @@ -199,11 +200,12 @@ function extractHintsFrom( if (hints["suggestions"]) { const suggestions = hints["suggestions"] - const f = new Function("{ layers, themes, validators }", suggestions) + const f = new Function("{ layers, themes, validators, Constants }", suggestions) hints["suggestions"] = f({ layers: AllSharedLayers.sharedLayers, themes: AllKnownLayouts.allKnownLayouts, validators: Validators, + Constants: Constants }) } return hints diff --git a/src/Models/Constants.ts b/src/Models/Constants.ts index 326087e09..e8e080130 100644 --- a/src/Models/Constants.ts +++ b/src/Models/Constants.ts @@ -114,27 +114,42 @@ export default class Constants { * These are the values that are allowed to use as 'backdrop' icon for a map pin */ private static readonly _defaultPinIcons = [ + "pin", "square", "circle", - "none", - "pin", - "person", - "plus", - "ring", - "star", - "teardrop", - "triangle", + "checkmark", + "clock", + "close", "crosshair", + "help", + "home", + "invalid", + "location", + "location_empty", + "location_locked", + "note", + "resolved", + "ring", + "scissors", + "teardrop", + "teardrop_with_hole_green", + "triangle", "brick_wall_square", "brick_wall_round", "gps_arrow", "checkmark", "help", - "clock", - "invalid", "close", + "invalid", "heart", "heart_outline", + "confirm", + "direction", + "not_found", + "mastodon", + "party", + "addSmall", + ] as const public static readonly defaultPinIcons: string[] = Constants._defaultPinIcons diff --git a/src/Models/ThemeConfig/Conversion/Validation.ts b/src/Models/ThemeConfig/Conversion/Validation.ts index 2f46cc3c1..56dcfca75 100644 --- a/src/Models/ThemeConfig/Conversion/Validation.ts +++ b/src/Models/ThemeConfig/Conversion/Validation.ts @@ -24,6 +24,7 @@ import { ConversionContext } from "./ConversionContext" import * as eli from "../../../assets/editor-layer-index.json" import { AvailableRasterLayers } from "../../RasterLayers" import Back from "../../../assets/svg/Back.svelte" +import PointRenderingConfigJson from "../Json/PointRenderingConfigJson" class ValidateLanguageCompleteness extends DesugaringStep { private readonly _languages: string[] @@ -1012,6 +1013,7 @@ export class PrevalidateLayer extends DesugaringStep { */ private readonly _path: string private readonly _studioValidations: boolean + private readonly _validatePointRendering = new ValidatePointRendering() constructor(path: string, isBuiltin, doesImageExist, studioValidations) { super("Runs various checks against common mistakes for a layer", [], "PrevalidateLayer") @@ -1101,6 +1103,8 @@ export class PrevalidateLayer extends DesugaringStep { context.enter("pointRendering").err("There are no pointRenderings at all...") } + json.pointRendering?.forEach((pr,i) => this._validatePointRendering.convert(pr, context.enters("pointeRendering", i))) + if (json["mapRendering"]) { context.enter("mapRendering").err("This layer has a legacy 'mapRendering'") } @@ -1405,13 +1409,40 @@ export class ValidateLayerConfig extends DesugaringStep { } } +class ValidatePointRendering extends DesugaringStep { + constructor() { + super("Various checks for pointRenderings", [], "ValidatePOintRendering") + } + + convert(json: PointRenderingConfigJson, context: ConversionContext): PointRenderingConfigJson { + if (json.marker === undefined && json.label === undefined) { + context.err(`A point rendering should define at least an marker or a label`) + } + + if (json["markers"]) { + context.enter("markers").err(`Detected a field 'markerS' in pointRendering. It is written as a singular case`) + } + if (json.marker && !Array.isArray(json.marker)) { + context.enter("marker").err( + "The marker in a pointRendering should be an array" + ) + } + if (json.location.length == 0) { + context.enter("location").err ( + "A pointRendering should have at least one 'location' to defined where it should be rendered. " + ) + } + return json + + + } +} export class ValidateLayer extends Conversion< LayerConfigJson, { parsed: LayerConfig; raw: LayerConfigJson } > { private readonly _skipDefaultLayers: boolean private readonly _prevalidation: PrevalidateLayer - constructor( path: string, isBuiltin: boolean, diff --git a/src/Models/ThemeConfig/Json/LayerConfigJson.ts b/src/Models/ThemeConfig/Json/LayerConfigJson.ts index b161e8727..ef3b43196 100644 --- a/src/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/src/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -506,7 +506,7 @@ export interface LayerConfigJson { * If the way is part of a relation, MapComplete will attempt to update this relation as well * question: Should the contributor be able to split ways using this layer? * iftrue: enable the 'split-roads'-component - * iffalse: don't enable the split-roads componenet + * iffalse: don't enable the split-roads component * ifunset: don't enable the split-roads component * group: editing */ diff --git a/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts b/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts index d4b69157f..96e94481b 100644 --- a/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts +++ b/src/Models/ThemeConfig/Json/PointRenderingConfigJson.ts @@ -5,7 +5,7 @@ export interface IconConfigJson { /** * question: What icon should be used? * type: icon - * suggestions: return ["pin","square","circle","checkmark","clock","close","crosshair","help","home","invalid","location","location_empty","location_locked","note","resolved","ring","scissors","teardrop","teardrop_with_hole_green","triangle"].map(i => ({if: "value="+i, then: i, icon: i})) + * suggestions: return Constants.defaultPinIcons.map(i => ({if: "value="+i, then: i, icon: i})) */ icon: string | MinimalTagRenderingConfigJson | { builtin: string; override: any } /** diff --git a/src/Models/ThemeConfig/PointRenderingConfig.ts b/src/Models/ThemeConfig/PointRenderingConfig.ts index 84a4ecfe4..a522c45a7 100644 --- a/src/Models/ThemeConfig/PointRenderingConfig.ts +++ b/src/Models/ThemeConfig/PointRenderingConfig.ts @@ -79,23 +79,7 @@ export default class PointRenderingConfig extends WithContextLoader { } }) - if (json.marker === undefined && json.label === undefined) { - throw `At ${context}: A point rendering should define at least an marker or a label` - } - if (json["markers"]) { - throw `At ${context}.markers: detected a field 'markerS' in pointRendering. It is written as a singular case` - } - if (json.marker && !Array.isArray(json.marker)) { - throw `At ${context}.marker: the marker in a pointRendering should be an array` - } - if (this.location.size == 0) { - throw ( - "A pointRendering should have at least one 'location' to defined where it should be rendered. (At " + - context + - ".location)" - ) - } this.marker = (json.marker ?? []).map((m) => new IconConfig(m)) if (json.css !== undefined) { this.cssDef = this.tr("css", undefined) diff --git a/src/Models/ThemeConfig/TagRenderingConfig.ts b/src/Models/ThemeConfig/TagRenderingConfig.ts index 06106a7de..4d8a0a4f6 100644 --- a/src/Models/ThemeConfig/TagRenderingConfig.ts +++ b/src/Models/ThemeConfig/TagRenderingConfig.ts @@ -371,20 +371,9 @@ export default class TagRenderingConfig { let iconClass = commonSize if (!!mapping.icon) { if (typeof mapping.icon === "string" && mapping.icon !== "") { - let stripped = mapping.icon - if (stripped.endsWith(".svg")) { - stripped = stripped.substring(0, stripped.length - 4) - } - if (Constants.defaultPinIcons.indexOf(stripped) >= 0) { - icon = "./assets/svg/" + mapping.icon - if (!icon.endsWith(".svg")) { - icon += ".svg" - } - } else { - icon = mapping.icon - } + icon = mapping.icon.trim() } else if (mapping.icon["path"]) { - icon = mapping.icon["path"] + icon = mapping.icon["path"].trim() iconClass = mapping.icon["class"] ?? iconClass } } diff --git a/src/UI/BigComponents/OpenBackgroundSelectorButton.svelte b/src/UI/BigComponents/OpenBackgroundSelectorButton.svelte index 3c2cb555f..e617e877d 100644 --- a/src/UI/BigComponents/OpenBackgroundSelectorButton.svelte +++ b/src/UI/BigComponents/OpenBackgroundSelectorButton.svelte @@ -1,7 +1,7 @@ diff --git a/src/UI/Map/Icon.svelte b/src/UI/Map/Icon.svelte index 7bec894bc..d1d4223aa 100644 --- a/src/UI/Map/Icon.svelte +++ b/src/UI/Map/Icon.svelte @@ -1,46 +1,47 @@ {#if icon} @@ -99,9 +100,9 @@ {:else if icon === "invalid"} {:else if icon === "heart"} - + {:else if icon === "heart_outline"} - + {:else if icon === "confirm"} {:else if icon === "direction"} @@ -118,3 +119,4 @@ {/if} {/if} + diff --git a/src/UI/Popup/TagRendering/TagRenderingEditable.svelte b/src/UI/Popup/TagRendering/TagRenderingEditable.svelte index 797c2503b..37f737f82 100644 --- a/src/UI/Popup/TagRendering/TagRenderingEditable.svelte +++ b/src/UI/Popup/TagRendering/TagRenderingEditable.svelte @@ -27,7 +27,7 @@ /** * Indicates if this tagRendering currently shows the attribute or asks the question to _change_ the property */ - export let editMode = !config.IsKnown(tags.data) // || showQuestionIfUnknown; + export let editMode = !config.IsKnown(tags.data) if (tags) { onDestroy( tags.addCallbackD((tags) => { diff --git a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte index aeaf3c0da..93ceda4d6 100644 --- a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte +++ b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte @@ -159,7 +159,7 @@ } } - function onSave() { + function onSave(e) { if (selectedTags === undefined) { return } diff --git a/src/UI/Studio/ArrayMultiAnswer.svelte b/src/UI/Studio/ArrayMultiAnswer.svelte index 7c8e5b6d5..0af7e7bc5 100644 --- a/src/UI/Studio/ArrayMultiAnswer.svelte +++ b/src/UI/Studio/ArrayMultiAnswer.svelte @@ -41,7 +41,6 @@ diff --git a/src/UI/Studio/QuestionPreview.svelte b/src/UI/Studio/QuestionPreview.svelte index 765772c26..3bcb6025f 100644 --- a/src/UI/Studio/QuestionPreview.svelte +++ b/src/UI/Studio/QuestionPreview.svelte @@ -117,7 +117,6 @@ selectedElement={state.exampleFeature} {config} editingEnabled={new ImmutableStore(true)} - showQuestionIfUnknown={true} {state} {tags} /> diff --git a/src/UI/Studio/SchemaBasedField.svelte b/src/UI/Studio/SchemaBasedField.svelte index dd87e9af8..c5a7d581b 100644 --- a/src/UI/Studio/SchemaBasedField.svelte +++ b/src/UI/Studio/SchemaBasedField.svelte @@ -187,7 +187,6 @@ editMode={startInEditMode} {config} selectedElement={undefined} - showQuestionIfUnknown={true} {state} {tags} /> diff --git a/src/UI/Studio/SchemaBasedMultiType.svelte b/src/UI/Studio/SchemaBasedMultiType.svelte index b66df015c..c6ff4f192 100644 --- a/src/UI/Studio/SchemaBasedMultiType.svelte +++ b/src/UI/Studio/SchemaBasedMultiType.svelte @@ -215,7 +215,6 @@ diff --git a/src/UI/Studio/TagRenderingInput.svelte b/src/UI/Studio/TagRenderingInput.svelte index e425ab44a..41e01a220 100644 --- a/src/UI/Studio/TagRenderingInput.svelte +++ b/src/UI/Studio/TagRenderingInput.svelte @@ -139,7 +139,6 @@ diff --git a/src/UI/Test.svelte b/src/UI/Test.svelte index 5331a9d83..c4d5d1823 100644 --- a/src/UI/Test.svelte +++ b/src/UI/Test.svelte @@ -1,16 +1,7 @@ -Acc: {$maxAcc} -{#if $recentlyShaken} -
SHAKEN
-{/if} + diff --git a/src/assets/schemas/layerconfigmeta.json b/src/assets/schemas/layerconfigmeta.json index 901780eab..e7c724528 100644 --- a/src/assets/schemas/layerconfigmeta.json +++ b/src/assets/schemas/layerconfigmeta.json @@ -253,7 +253,7 @@ "question": "What extra attributes should be calculated with javascript?" }, "type": "array", - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" }, { "path": [ @@ -1770,6 +1770,81 @@ "if": "value=triangle", "then": "triangle", "icon": "triangle" + }, + { + "if": "value=brick_wall_square", + "then": "brick_wall_square", + "icon": "brick_wall_square" + }, + { + "if": "value=brick_wall_round", + "then": "brick_wall_round", + "icon": "brick_wall_round" + }, + { + "if": "value=gps_arrow", + "then": "gps_arrow", + "icon": "gps_arrow" + }, + { + "if": "value=checkmark", + "then": "checkmark", + "icon": "checkmark" + }, + { + "if": "value=help", + "then": "help", + "icon": "help" + }, + { + "if": "value=close", + "then": "close", + "icon": "close" + }, + { + "if": "value=invalid", + "then": "invalid", + "icon": "invalid" + }, + { + "if": "value=heart", + "then": "heart", + "icon": "heart" + }, + { + "if": "value=heart_outline", + "then": "heart_outline", + "icon": "heart_outline" + }, + { + "if": "value=confirm", + "then": "confirm", + "icon": "confirm" + }, + { + "if": "value=direction", + "then": "direction", + "icon": "direction" + }, + { + "if": "value=not_found", + "then": "not_found", + "icon": "not_found" + }, + { + "if": "value=mastodon", + "then": "mastodon", + "icon": "mastodon" + }, + { + "if": "value=party", + "then": "party", + "icon": "party" + }, + { + "if": "value=addSmall", + "then": "addSmall", + "icon": "addSmall" } ] }, @@ -10403,7 +10478,7 @@ }, { "if": "value=unit", - "then": "unit - Library layer with all common units" + "then": "unit - Library layer with all common units. Units can _only_ be imported from this file." }, { "if": "value=usersettings", @@ -10574,6 +10649,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -10971,6 +11057,97 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "tagRenderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "tagRenderings", @@ -11324,6 +11501,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -11544,6 +11725,23 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "tagRenderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "tagRenderings", @@ -12108,6 +12306,100 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "tagRenderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "tagRenderings", @@ -12474,6 +12766,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -12704,6 +13000,24 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "tagRenderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "tagRenderings", @@ -13290,6 +13604,100 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "tagRenderings", @@ -13656,6 +14064,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -13886,6 +14298,24 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "tagRenderings", @@ -14472,6 +14902,103 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "tagRenderings", @@ -14851,6 +15378,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -15091,6 +15622,2652 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "tagRenderings", + "renderings", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "tagRenderings", + "renderings", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "tagRenderings", + "renderings", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "tagRenderings", + "renderings", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "tagRenderings", + "renderings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "tagRenderings", + "renderings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "tagRenderings", + "renderings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "tagRenderings", + "renderings", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "tagRenderings", + "renderings", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "tagRenderings", + "renderings", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "tagRenderings", diff --git a/src/assets/schemas/layoutconfigmeta.json b/src/assets/schemas/layoutconfigmeta.json index 4f51c924a..53e2252da 100644 --- a/src/assets/schemas/layoutconfigmeta.json +++ b/src/assets/schemas/layoutconfigmeta.json @@ -834,7 +834,7 @@ }, { "if": "value=unit", - "then": "unit - Library layer with all common units" + "then": "unit - Library layer with all common units. Units can _only_ be imported from this file." }, { "if": "value=usersettings", @@ -966,7 +966,7 @@ ] }, "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]\n\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]\n\ngroup: expert\nquestion: What extra attributes should be calculated with javascript?", "type": "array", "items": { "type": "string" @@ -1419,6 +1419,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -1727,7 +1738,7 @@ "$ref": "#/definitions/default_2" }, { - "$ref": "#/definitions/Record" + "$ref": "#/definitions/Record" } ] } @@ -2055,7 +2066,7 @@ "question": "What extra attributes should be calculated with javascript?" }, "type": "array", - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" }, { "path": [ @@ -3627,6 +3638,81 @@ "if": "value=triangle", "then": "triangle", "icon": "triangle" + }, + { + "if": "value=brick_wall_square", + "then": "brick_wall_square", + "icon": "brick_wall_square" + }, + { + "if": "value=brick_wall_round", + "then": "brick_wall_round", + "icon": "brick_wall_round" + }, + { + "if": "value=gps_arrow", + "then": "gps_arrow", + "icon": "gps_arrow" + }, + { + "if": "value=checkmark", + "then": "checkmark", + "icon": "checkmark" + }, + { + "if": "value=help", + "then": "help", + "icon": "help" + }, + { + "if": "value=close", + "then": "close", + "icon": "close" + }, + { + "if": "value=invalid", + "then": "invalid", + "icon": "invalid" + }, + { + "if": "value=heart", + "then": "heart", + "icon": "heart" + }, + { + "if": "value=heart_outline", + "then": "heart_outline", + "icon": "heart_outline" + }, + { + "if": "value=confirm", + "then": "confirm", + "icon": "confirm" + }, + { + "if": "value=direction", + "then": "direction", + "icon": "direction" + }, + { + "if": "value=not_found", + "then": "not_found", + "icon": "not_found" + }, + { + "if": "value=mastodon", + "then": "mastodon", + "icon": "mastodon" + }, + { + "if": "value=party", + "then": "party", + "icon": "party" + }, + { + "if": "value=addSmall", + "then": "addSmall", + "icon": "addSmall" } ] }, @@ -12523,7 +12609,7 @@ }, { "if": "value=unit", - "then": "unit - Library layer with all common units" + "then": "unit - Library layer with all common units. Units can _only_ be imported from this file." }, { "if": "value=usersettings", @@ -12696,6 +12782,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -13102,6 +13199,100 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "tagRenderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -13468,6 +13659,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -13698,6 +13893,24 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "tagRenderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -14284,6 +14497,103 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "tagRenderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -14663,6 +14973,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -14903,6 +15217,25 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "tagRenderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -15512,6 +15845,103 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -15891,6 +16321,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -16131,6 +16565,25 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -16739,6 +17192,106 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -17131,6 +17684,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -17381,6 +17938,2751 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "layers", + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -18820,7 +22122,7 @@ "question": "What extra attributes should be calculated with javascript?" }, "type": "array", - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\nNot found... * \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\nIf a tag has to be evaluated strictly, use ':=' instead:\n[\n\"_some_key:=some_javascript_expression\"\n]\nSee the full documentation on [https://github.com/pietervdvn/MapComplete/blob/master/Docs/CalculatedTags.md]" }, { "path": [ @@ -20447,6 +23749,81 @@ "if": "value=triangle", "then": "triangle", "icon": "triangle" + }, + { + "if": "value=brick_wall_square", + "then": "brick_wall_square", + "icon": "brick_wall_square" + }, + { + "if": "value=brick_wall_round", + "then": "brick_wall_round", + "icon": "brick_wall_round" + }, + { + "if": "value=gps_arrow", + "then": "gps_arrow", + "icon": "gps_arrow" + }, + { + "if": "value=checkmark", + "then": "checkmark", + "icon": "checkmark" + }, + { + "if": "value=help", + "then": "help", + "icon": "help" + }, + { + "if": "value=close", + "then": "close", + "icon": "close" + }, + { + "if": "value=invalid", + "then": "invalid", + "icon": "invalid" + }, + { + "if": "value=heart", + "then": "heart", + "icon": "heart" + }, + { + "if": "value=heart_outline", + "then": "heart_outline", + "icon": "heart_outline" + }, + { + "if": "value=confirm", + "then": "confirm", + "icon": "confirm" + }, + { + "if": "value=direction", + "then": "direction", + "icon": "direction" + }, + { + "if": "value=not_found", + "then": "not_found", + "icon": "not_found" + }, + { + "if": "value=mastodon", + "then": "mastodon", + "icon": "mastodon" + }, + { + "if": "value=party", + "then": "party", + "icon": "party" + }, + { + "if": "value=addSmall", + "then": "addSmall", + "icon": "addSmall" } ] }, @@ -29606,7 +32983,7 @@ }, { "if": "value=unit", - "then": "unit - Library layer with all common units" + "then": "unit - Library layer with all common units. Units can _only_ be imported from this file." }, { "if": "value=usersettings", @@ -29781,6 +33158,17 @@ } ] }, + "editButtonAriaLabel": { + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time.", + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ] + }, "labels": { "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer", "type": "array", @@ -30196,6 +33584,103 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -30575,6 +34060,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -30815,6 +34304,25 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -31423,6 +34931,106 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -31815,6 +35423,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -32065,6 +35677,26 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -32697,6 +36329,106 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -33089,6 +36821,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -33339,6 +37075,26 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", @@ -33969,6 +37725,109 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "layers", @@ -34374,6 +38233,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -34634,6 +38497,2850 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "labels" + ], + "required": false, + "hints": {}, + "type": "array", + "description": "A list of labels. These are strings that are used for various purposes, e.g. to only include a subset of the tagRenderings when reusing a layer" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "render" + ], + "required": false, + "hints": { + "typehint": "rendered", + "question": "What text should be rendered?", + "ifunset": "No text is shown if no predefined options match." + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "object", + "properties": { + "special": { + "allOf": [ + { + "$ref": "#/definitions/Record>" + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ] + } + ] + } + }, + "required": [ + "special" + ] + }, + { + "type": "string" + } + ], + "description": "This piece of text will be shown in the infobox.\nIn this text, values within braces (such as {braced(key)}) are replaced by the corresponding `value` in the object.\nFor example, if the object contains tags `amenity=school; name=Windy Hill School`, the render string `This school is named {name}` will be shown to the user as `This school is named Windy Hill School`\nThis text will be shown if:\n- there is no mapping which matches (or there are no matches)\n- no question, no mappings and no 'freeform' is set\nNote that this is a HTML-interpreted value, so you can add links as e.g. '<a href='{website}'>{website}</a>' or include images such as `This is of type A <br><img src='typeA-icon.svg' />`" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "what icon should be shown next to the 'render' value?", + "ifunset": "No additional icon is shown next to the always shown text" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "An icon shown next to the rendering; typically shown pretty small\nThis is only shown next to the \"render\" value" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "condition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown?", + "ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "condition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "condition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "metacondition" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "When should this item be shown (including special conditions)?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "metacondition", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "metacondition", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "description" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A human-readable text explaining what this tagRendering does.\nMostly used for the shared tagrenderings" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "classes" + ], + "required": false, + "hints": { + "question": "What css-classes should be applied to showing this attribute?" + }, + "type": "string", + "description": "A list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\nValues are split on ` ` (space)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings" + ], + "required": false, + "hints": { + "question": "What are common options?" + }, + "type": "array", + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "if" + ], + "required": true, + "hints": { + "typehint": "tag", + "question": "What tags should be matched to show this option?" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "If in 'question'-mode and the contributor selects this option, these tags will be applied to the object" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "then" + ], + "required": true, + "hints": { + "typehint": "rendered", + "question": "What corresponding text should be shown?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "Shown if the `if` is fulfilled" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon" + ], + "required": false, + "hints": { + "typehint": "icon", + "question": "What icon should be shown next to this mapping?", + "ifunset": "Show no icon" + }, + "type": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "path" + ] + }, + { + "type": "string" + } + ], + "description": "This icon will only be shown if the value is known, it is not displayed in the options (but might be in the future)" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "path" + ], + "required": true, + "hints": { + "typehint": "icon" + }, + "type": "string", + "description": "The path to the icon" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "icon", + "class" + ], + "required": false, + "hints": {}, + "type": "string", + "description": "Size of the image" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer" + ], + "required": false, + "hints": { + "typehint": "tag", + "question": "Under what circumstances should this mapping be hidden from the possibilities a contributor can pick?", + "iftrue": "Never show this mapping as option to pick", + "ifunset": "Always show this mapping as option to pick" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": [ + "string", + "boolean" + ] + } + ], + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\nTo demonstrate an example making a default assumption:\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n ]\n}\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "hideInAnswer", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot" + ], + "required": false, + "hints": { + "question": "What tags should be applied if this mapping is _not_ chosen?", + "ifunset": "Do not apply a tag if a different mapping is chosen." + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "ifnot", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "addExtraTags" + ], + "required": false, + "hints": { + "typehint": "simple_tag", + "question": "What extra tags should be added to the object if this object is chosen?" + }, + "type": "array", + "description": "If chosen as answer, these tags will be applied onto the object, together with the tags from the `if`\nNot compatible with multiAnswer.\nThis can be used e.g. to erase other keys which indicate the 'not' value:\n```json\n{\n \"if\": \"crossing:marking=rainbow\",\n \"then\": \"This is a rainbow crossing\",\n \"addExtraTags\": [\"not:crossing:marking=\"]\n}\n```" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "searchTerms" + ], + "required": false, + "hints": { + "group": "hidden", + "question": "If there are many options, what search terms match too?" + }, + "type": "object", + "description": "If there are many options, the mappings-radiobuttons will be replaced by an element with a searchfunction\nSearchterms (per language) allow to easily find an option if there are many options" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "If the searchable selector is picked, mappings with this item will have priority and show up even if the others are hidden\nUse this sparingly" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "priorityIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "mappings", + "#" + ], + "required": false, + "hints": { + "group": "hidden" + }, + "type": "string", + "description": "Used for comments or to disable a validation\nignore-image-in-then: normally, a `then`-clause is not allowed to have an `img`-html-element as icons are preferred. In some cases (most notably title-icons), this is allowed" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "multiAnswer" + ], + "required": false, + "hints": { + "question": "Should a contributor be allowed to select multiple mappings?", + "iftrue": "allow to select multiple mappings", + "iffalse": "only allow to select a single mapping", + "ifunset": "only allow to select a single mapping" + }, + "type": "boolean", + "description": "If true, use checkboxes instead of radio buttons when asking the question" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform" + ], + "required": false, + "hints": {}, + "type": "object", + "description": "Allow freeform text input from the user" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "key" + ], + "required": false, + "hints": { + "question": "What is the name of the attribute that should be written to?", + "ifunset": "do not offer a freeform textfield as answer option" + }, + "type": "string", + "description": "This is the OpenStreetMap-key that that value will be written to" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "type" + ], + "required": false, + "hints": { + "question": "What is the input type?", + "ifunset": "use an unconstrained string as input (default)", + "suggestions": [ + { + "if": "value=string", + "then": "string A simple piece of text" + }, + { + "if": "value=text", + "then": "text A longer piece of text. Uses an textArea instead of a textField" + }, + { + "if": "value=date", + "then": "date A date with date picker" + }, + { + "if": "value=nat", + "then": "nat A whole, positive number or zero" + }, + { + "if": "value=int", + "then": "int A whole number, either positive, negative or zero" + }, + { + "if": "value=distance", + "then": "distance A geographical distance in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]" + }, + { + "if": "value=direction", + "then": "direction A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)." + }, + { + "if": "value=wikidata", + "then": "wikidata A wikidata identifier, e.g. Q42. " + }, + { + "if": "value=pnat", + "then": "pnat A strict positive number" + }, + { + "if": "value=float", + "then": "float A decimal number" + }, + { + "if": "value=pfloat", + "then": "pfloat A positive decimal number or zero" + }, + { + "if": "value=email", + "then": "email An email adress" + }, + { + "if": "value=url", + "then": "url The validatedTextField will format URLs to always be valid and have a https://-header (even though the 'https'-part will be hidden from the user. Furthermore, some tracking parameters will be removed" + }, + { + "if": "value=phone", + "then": "phone A phone number" + }, + { + "if": "value=opening_hours", + "then": "opening_hours Has extra elements to easily input when a POI is opened. " + }, + { + "if": "value=color", + "then": "color Shows a color picker" + }, + { + "if": "value=icon", + "then": "icon Makes sure that a valid .svg-path is added" + }, + { + "if": "value=fediverse", + "then": "fediverse Validates fediverse addresses and normalizes them into `@username@server`-format" + }, + { + "if": "value=id", + "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." + } + ] + }, + "type": "string", + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "placeholder" + ], + "required": false, + "hints": { + "typehint": "translation", + "group": "expert", + "question": "What placeholder text should be shown in the input-element if there is no input?" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "helperArgs" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "addExtraTags" + ], + "required": false, + "hints": { + "group": "expert" + }, + "type": "array", + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "inline" + ], + "required": false, + "hints": { + "group": "expert", + "question": "Show the freeform as box within the question?", + "iftrue": "show the freeform input field as a small field within the question", + "ifunset": "show the freeform input field full-width" + }, + "type": "boolean", + "description": "Instead of showing a full-width text field, the text field will be shown within the rendering of the question.\nThis combines badly with special input elements, as it'll distort the layout." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "default" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What value should be entered in the text field if no value is set?", + "ifunset": "do not prefill the textfield" + }, + "type": "string", + "description": "This can help people to quickly enter the most common option" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues" + ], + "required": false, + "hints": { + "group": "expert", + "question": "What values of the freeform key should be interpreted as 'unknown'?", + "ifunset": "The question will be considered answered if any value is set for the key" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "For example, if a feature has `shop=yes`, the question 'what type of shop is this?' should still asked" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "freeform", + "invalidValues", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "question" + ], + "required": false, + "hints": { + "question": "What question should be shown to the contributor?", + "ifunset": "This tagrendering will be shown if it is known, but cannot be edited by the contributor, effectively resutling in a read-only rendering" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "A question is presented ot the user if no mapping matches and the 'freeform' key is not set as well." + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "questionHint" + ], + "required": false, + "hints": { + "question": "Should some extra information be shown to the contributor, alongside the question?", + "ifunset": "No extra hint is given" + }, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" + }, + { + "path": [ + "layers", + "override", + "tagRenderings", + "renderings", + "override", + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "layers", diff --git a/src/assets/schemas/questionabletagrenderingconfigmeta.json b/src/assets/schemas/questionabletagrenderingconfigmeta.json index 67a6c4aa3..a1e090956 100644 --- a/src/assets/schemas/questionabletagrenderingconfigmeta.json +++ b/src/assets/schemas/questionabletagrenderingconfigmeta.json @@ -225,6 +225,94 @@ ], "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" }, + { + "path": [ + "mappings", + "alsoShowIf" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "$ref": "#/definitions/{or:TagConfigJson[];}" + }, + { + "type": "string" + } + ], + "description": "Also show this 'then'-option if the feature matches these tags.\nIdeal for outdated tags." + }, + { + "path": [ + "mappings", + "alsoShowIf", + "and" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, + { + "path": [ + "mappings", + "alsoShowIf", + "or" + ], + "required": false, + "hints": { + "typehint": "tag" + }, + "type": [ + { + "$ref": "#/definitions/{and:TagConfigJson[];}" + }, + { + "type": "object", + "properties": { + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/TagConfigJson" + } + } + }, + "required": [ + "or" + ] + }, + { + "type": "string" + } + ], + "description": "The main representation of Tags.\nSee https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Tags_format.md for more documentation" + }, { "path": [ "mappings", @@ -565,6 +653,10 @@ { "if": "value=id", "then": "id Checks for valid identifiers for layers, will automatically replace spaces and uppercase" + }, + { + "if": "value=slope", + "then": "slope Validates that the slope is a valid number.The accompanying input element uses the gyroscope and the compass to determine the correct incline. The sign of the incline will be set automatically. The bearing of the way is compared to the bearing of the compass, as such, the device knows if it is measuring in the forward or backward direction." } ] }, @@ -775,6 +867,22 @@ ], "description": "This hint is shown in subtle text under the question.\nThis can give some extra information on what the answer should ook like" }, + { + "path": [ + "editButtonAriaLabel" + ], + "required": false, + "hints": {}, + "type": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "string" + } + ], + "description": "When using a screenreader and selecting the 'edit' button, the current rendered value is read aloud in normal circumstances.\nIn some rare cases, this is not desirable. For example, if the rendered value is a link to a website, this link can be selected (and will be read aloud).\nIf the user presses _tab_ again, they'll select the button and have the link read aloud a second time." + }, { "path": [ "labels" diff --git a/src/index.css b/src/index.css index fe4be9045..9b3072a15 100644 --- a/src/index.css +++ b/src/index.css @@ -53,6 +53,9 @@ --image-carousel-height: 350px; + /** Technical value, used by icon.svelte + */ + --svg-color: #000000; } /***********************************************************************\ @@ -612,6 +615,10 @@ a.link-underline { overflow: visible !important; } +svg.apply-fill path { + fill: var(--svg-color) +} + .compass_arrow { width: calc( 2.5rem - 1px ) ; height: calc( 2.5rem - 1px )