From 1625b21138c19d4edbcfeef784fd2a4c5680a448 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sun, 23 Aug 2020 02:26:17 +0200 Subject: [PATCH] More work on the theme generator --- Customizations/JSON/CustomLayoutFromJSON.ts | 54 +++++++++---------- Customizations/LayerDefinition.ts | 35 ++++++++++++ assets/themes/artwork/artwork.json | 2 + .../artwork/artwork.svg} | 0 assets/themes/bookcases/Bookcases.json | 4 ++ assets/themes/toilets/toilets.json | 3 +- test/Tag.spec.ts | 7 ++- 7 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 assets/themes/artwork/artwork.json rename assets/{statue.svg => themes/artwork/artwork.svg} (100%) diff --git a/Customizations/JSON/CustomLayoutFromJSON.ts b/Customizations/JSON/CustomLayoutFromJSON.ts index 078bf58..5c69f96 100644 --- a/Customizations/JSON/CustomLayoutFromJSON.ts +++ b/Customizations/JSON/CustomLayoutFromJSON.ts @@ -8,6 +8,7 @@ import FixedText from "../Questions/FixedText"; import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; import {UIEventSource} from "../../Logic/UIEventSource"; import {TagDependantUIElementConstructor} from "../UIElementConstructor"; +import {Map} from "../Layers/Map"; export interface TagRenderingConfigJson { @@ -20,7 +21,9 @@ export interface TagRenderingConfigJson { // If it is not known (and no mapping below matches), this question is asked; a textfield is inserted in the rendering above question?: string, // If a value is added with the textfield, this extra tag is addded. Optional field - addExtraTags?: string | string[] | { k: string, v: string }[]; + addExtraTags?: string | { k: string, v: string }[]; + // Extra tags: rendering is only shown/asked if these tags are present + condition?: string; // Alternatively, these tags are shown if they match - even if the key above is not there // If unknown, these become a radio button mappings?: @@ -33,26 +36,16 @@ export interface TagRenderingConfigJson { export interface LayerConfigJson { id: string; - icon: TagRenderingConfigJson; - title: TagRenderingConfigJson; - description: string; - minzoom: number, - color: TagRenderingConfigJson; - width: TagRenderingConfigJson; - overpassTags: string | string[] | { k: string, v: string }[]; + title: string | any | TagRenderingConfigJson; + description: string | any; + minzoom: number | string, + icon?: TagRenderingConfigJson; + color?: TagRenderingConfigJson; + width?: TagRenderingConfigJson; + overpassTags: string | { k: string, v: string }[]; wayHandling: number, - presets: [ - { - // icon: optional. Uses the layer icon by default - icon?: string; - // title: optional. Uses the layer title by default - title?: string; - // description: optional. Uses the layer description by default - description?: string; - // tags: optional list {k:string, v:string}[] - tags?: string | string[] | { k: string, v: string }[] - } - ], + presets: Preset[] + , tagRenderings: TagRenderingConfigJson [] } @@ -80,7 +73,7 @@ export class CustomLayoutFromJSON { return CustomLayoutFromJSON.LayoutFromJSON(JSON.parse(atob(layoutFromBase64))); } - public static TagRenderingFromJson(json: any): TagDependantUIElementConstructor { + public static TagRenderingFromJson(json: TagRenderingConfigJson): TagDependantUIElementConstructor { if(json === undefined){ return undefined; @@ -147,7 +140,7 @@ export class CustomLayoutFromJSON { } } - private static StyleFromJson(layout: any, styleJson: any): ((tags: any) => { + private static StyleFromJson(layout: LayerConfigJson): ((tags: any) => { color: string, weight?: number, icon: { @@ -224,7 +217,7 @@ export class CustomLayoutFromJSON { if (typeof (json) === "string") { tags = json.split("&").map(CustomLayoutFromJSON.TagFromJson); } else { - tags = json.map(CustomLayoutFromJSON.TagFromJson); + tags = json.map(x => {CustomLayoutFromJSON.TagFromJson(x)}); } for (const tag of tags) { if (tag === undefined) { @@ -234,7 +227,7 @@ export class CustomLayoutFromJSON { return tags; } - private static LayerFromJson(json: any): LayerDefinition { + private static LayerFromJson(json: LayerConfigJson): LayerDefinition { const t = CustomLayoutFromJSON.MaybeTranslation; const tr = CustomLayoutFromJSON.TagRenderingFromJson; const tags = CustomLayoutFromJSON.TagsFromJson(json.overpassTags); @@ -250,7 +243,7 @@ export class CustomLayoutFromJSON { description: t(json.description), name: t(json.title.render), icon: icon, - minzoom: json.minzoom, + minzoom: parseInt(""+json.minzoom), title: tr(json.title), presets: json.presets.map((preset) => { return CustomLayoutFromJSON.PresetFromJson(json, preset) @@ -258,9 +251,9 @@ export class CustomLayoutFromJSON { elementsToShow: [new ImageCarouselWithUploadConstructor()].concat(json.tagRenderings.map(tr)), overpassFilter: new And(tags), - wayHandling: parseInt(json.wayHandling) ?? LayerDefinition.WAYHANDLING_CENTER_AND_WAY, + wayHandling: parseInt(""+json.wayHandling) ?? LayerDefinition.WAYHANDLING_CENTER_AND_WAY, maxAllowedOverlapPercentage: 0, - style: CustomLayoutFromJSON.StyleFromJson(json, json.style) + style: CustomLayoutFromJSON.StyleFromJson(json) } ) } @@ -276,7 +269,7 @@ export class CustomLayoutFromJSON { return new Translation(json); } - public static LayoutFromJSON(json: any) { + public static LayoutFromJSON(json: LayoutConfigJson) { const t = CustomLayoutFromJSON.MaybeTranslation; let languages = json.language; if(typeof (json.language) === "string"){ @@ -293,7 +286,10 @@ export class CustomLayoutFromJSON { ); layout.icon = json.icon; layout.maintainer = json.maintainer; - layout.widenFactor = parseFloat(json.widenFactor) ?? 0.03; + layout.widenFactor = parseFloat(""+json.widenFactor) ?? 0.03; + if(isNaN(layout.widenFactor)){ + layout.widenFactor = 0.03; + } if (layout.widenFactor > 0.1) { layout.widenFactor = 0.1; } diff --git a/Customizations/LayerDefinition.ts b/Customizations/LayerDefinition.ts index 1656da3..cbe3820 100644 --- a/Customizations/LayerDefinition.ts +++ b/Customizations/LayerDefinition.ts @@ -3,6 +3,7 @@ import {UIElement} from "../UI/UIElement"; import {TagDependantUIElementConstructor} from "./UIElementConstructor"; import {TagRenderingOptions} from "./TagRenderingOptions"; import Translation from "../UI/i18n/Translation"; +import {LayerConfigJson} from "./JSON/CustomLayoutFromJSON"; export interface Preset { tags: Tag[], @@ -127,4 +128,38 @@ export class LayerDefinition { this.wayHandling = options.wayHandling ?? LayerDefinition.WAYHANDLING_DEFAULT; } + + ToJson() { + + function t(translation: string | Translation | UIElement) { + if (translation === undefined) { + return undefined; + } + if (typeof (translation) === "string") { + return translation; + } + if (translation instanceof Translation && translation.translations !== undefined) { + return translation.translations; + } + return translation.InnerRender(); + } + + + const layerConfig /* : LayerConfigJson */= { + name: t(this.name), + description: t(this.description), + maxAllowedOverlapPercentage: this.maxAllowedOverlapPercentage, + presets: this.presets, + icon: this.icon, + minzoom: this.minzoom, + overpassFilter: this.overpassFilter, + title: this.title, + elementsToShow: this.elementsToShow, + style: this.style, + wayHandling: this.wayHandling, + + }; + + return JSON.stringify(layerConfig) + } } \ No newline at end of file diff --git a/assets/themes/artwork/artwork.json b/assets/themes/artwork/artwork.json new file mode 100644 index 0000000..c844f99 --- /dev/null +++ b/assets/themes/artwork/artwork.json @@ -0,0 +1,2 @@ + { +} \ No newline at end of file diff --git a/assets/statue.svg b/assets/themes/artwork/artwork.svg similarity index 100% rename from assets/statue.svg rename to assets/themes/artwork/artwork.svg diff --git a/assets/themes/bookcases/Bookcases.json b/assets/themes/bookcases/Bookcases.json index f86fd51..7100f5b 100644 --- a/assets/themes/bookcases/Bookcases.json +++ b/assets/themes/bookcases/Bookcases.json @@ -10,6 +10,10 @@ "en": "A public bookcase is a small streetside cabinet, box, old phone boot or some other objects where books are stored. Everyone can place or take a book. This map aims to collect all these bookcases. You can discover new bookcases nearby and, with a free OpenStreetMap account, quickly add your favourite bookcases.", "nl": "Een boekenruilkast is een kastje waar iedereen een boek kan nemen of achterlaten. Op deze kaart kan je deze boekenruilkasten terugvinden en met een gratis OpenStreetMap-account, ook boekenruilkasten toevoegen of informatie verbeteren" }, + "widenFactor": 0.05, + "startLat": 0, + "startLon": 0, + "startZoom": 10, "language": [ "en", "nl" diff --git a/assets/themes/toilets/toilets.json b/assets/themes/toilets/toilets.json index 43c885f..9a162ef 100644 --- a/assets/themes/toilets/toilets.json +++ b/assets/themes/toilets/toilets.json @@ -167,8 +167,9 @@ "maintainer": "Pieter Vander Vennet", "title": "Open Toilet Map", "startLon": "3.2222", + "widenFactor": 0.05, "icon": "./assets/themes/toilets/toilets.svg", "description": "A map of public toilets", - "language": "en", + "language": ["en"], "name": "toilets" } \ No newline at end of file diff --git a/test/Tag.spec.ts b/test/Tag.spec.ts index 3245070..66ac403 100644 --- a/test/Tag.spec.ts +++ b/test/Tag.spec.ts @@ -6,6 +6,7 @@ import {CustomLayoutFromJSON} from "../Customizations/JSON/CustomLayoutFromJSON" import {And} from "../Logic/TagsFilter"; import Translation from "../UI/i18n/Translation"; import T from "./TestHelper"; +import {Artwork} from "../Customizations/Layers/Artwork"; new T([ @@ -21,7 +22,7 @@ new T([ const tags = CustomLayoutFromJSON.TagsFromJson("highway~=residential|tertiary"); equal(""+tags[0].value, ""+/residential|tertiary/); console.log(tags[0].asOverpass()); - + } ], ["Tag replacement works in translation", () => { @@ -30,5 +31,9 @@ new T([ }).replace("{key}", "value"); equal(tr.txt, "Test value abc"); + }], + ["JSONify artwork layer", () => { + const a = new Artwork(); + console.log(a.ToJson()) }] ]);