More work on the theme generator

This commit is contained in:
Pieter Vander Vennet 2020-08-23 02:26:17 +02:00
parent 0f433d026a
commit 1625b21138
7 changed files with 74 additions and 31 deletions

View file

@ -8,6 +8,7 @@ import FixedText from "../Questions/FixedText";
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import {TagDependantUIElementConstructor} from "../UIElementConstructor"; import {TagDependantUIElementConstructor} from "../UIElementConstructor";
import {Map} from "../Layers/Map";
export interface TagRenderingConfigJson { 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 // If it is not known (and no mapping below matches), this question is asked; a textfield is inserted in the rendering above
question?: string, question?: string,
// If a value is added with the textfield, this extra tag is addded. Optional field // 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 // Alternatively, these tags are shown if they match - even if the key above is not there
// If unknown, these become a radio button // If unknown, these become a radio button
mappings?: mappings?:
@ -33,26 +36,16 @@ export interface TagRenderingConfigJson {
export interface LayerConfigJson { export interface LayerConfigJson {
id: string; id: string;
icon: TagRenderingConfigJson; title: string | any | TagRenderingConfigJson;
title: TagRenderingConfigJson; description: string | any;
description: string; minzoom: number | string,
minzoom: number, icon?: TagRenderingConfigJson;
color: TagRenderingConfigJson; color?: TagRenderingConfigJson;
width: TagRenderingConfigJson; width?: TagRenderingConfigJson;
overpassTags: string | string[] | { k: string, v: string }[]; overpassTags: string | { k: string, v: string }[];
wayHandling: number, wayHandling: number,
presets: [ presets: Preset[]
{ ,
// 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 }[]
}
],
tagRenderings: TagRenderingConfigJson [] tagRenderings: TagRenderingConfigJson []
} }
@ -80,7 +73,7 @@ export class CustomLayoutFromJSON {
return CustomLayoutFromJSON.LayoutFromJSON(JSON.parse(atob(layoutFromBase64))); return CustomLayoutFromJSON.LayoutFromJSON(JSON.parse(atob(layoutFromBase64)));
} }
public static TagRenderingFromJson(json: any): TagDependantUIElementConstructor { public static TagRenderingFromJson(json: TagRenderingConfigJson): TagDependantUIElementConstructor {
if(json === undefined){ if(json === undefined){
return 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, color: string,
weight?: number, weight?: number,
icon: { icon: {
@ -224,7 +217,7 @@ export class CustomLayoutFromJSON {
if (typeof (json) === "string") { if (typeof (json) === "string") {
tags = json.split("&").map(CustomLayoutFromJSON.TagFromJson); tags = json.split("&").map(CustomLayoutFromJSON.TagFromJson);
} else { } else {
tags = json.map(CustomLayoutFromJSON.TagFromJson); tags = json.map(x => {CustomLayoutFromJSON.TagFromJson(x)});
} }
for (const tag of tags) { for (const tag of tags) {
if (tag === undefined) { if (tag === undefined) {
@ -234,7 +227,7 @@ export class CustomLayoutFromJSON {
return tags; return tags;
} }
private static LayerFromJson(json: any): LayerDefinition { private static LayerFromJson(json: LayerConfigJson): LayerDefinition {
const t = CustomLayoutFromJSON.MaybeTranslation; const t = CustomLayoutFromJSON.MaybeTranslation;
const tr = CustomLayoutFromJSON.TagRenderingFromJson; const tr = CustomLayoutFromJSON.TagRenderingFromJson;
const tags = CustomLayoutFromJSON.TagsFromJson(json.overpassTags); const tags = CustomLayoutFromJSON.TagsFromJson(json.overpassTags);
@ -250,7 +243,7 @@ export class CustomLayoutFromJSON {
description: t(json.description), description: t(json.description),
name: t(json.title.render), name: t(json.title.render),
icon: icon, icon: icon,
minzoom: json.minzoom, minzoom: parseInt(""+json.minzoom),
title: tr(json.title), title: tr(json.title),
presets: json.presets.map((preset) => { presets: json.presets.map((preset) => {
return CustomLayoutFromJSON.PresetFromJson(json, preset) return CustomLayoutFromJSON.PresetFromJson(json, preset)
@ -258,9 +251,9 @@ export class CustomLayoutFromJSON {
elementsToShow: elementsToShow:
[new ImageCarouselWithUploadConstructor()].concat(json.tagRenderings.map(tr)), [new ImageCarouselWithUploadConstructor()].concat(json.tagRenderings.map(tr)),
overpassFilter: new And(tags), overpassFilter: new And(tags),
wayHandling: parseInt(json.wayHandling) ?? LayerDefinition.WAYHANDLING_CENTER_AND_WAY, wayHandling: parseInt(""+json.wayHandling) ?? LayerDefinition.WAYHANDLING_CENTER_AND_WAY,
maxAllowedOverlapPercentage: 0, maxAllowedOverlapPercentage: 0,
style: CustomLayoutFromJSON.StyleFromJson(json, json.style) style: CustomLayoutFromJSON.StyleFromJson(json)
} }
) )
} }
@ -276,7 +269,7 @@ export class CustomLayoutFromJSON {
return new Translation(json); return new Translation(json);
} }
public static LayoutFromJSON(json: any) { public static LayoutFromJSON(json: LayoutConfigJson) {
const t = CustomLayoutFromJSON.MaybeTranslation; const t = CustomLayoutFromJSON.MaybeTranslation;
let languages = json.language; let languages = json.language;
if(typeof (json.language) === "string"){ if(typeof (json.language) === "string"){
@ -293,7 +286,10 @@ export class CustomLayoutFromJSON {
); );
layout.icon = json.icon; layout.icon = json.icon;
layout.maintainer = json.maintainer; 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) { if (layout.widenFactor > 0.1) {
layout.widenFactor = 0.1; layout.widenFactor = 0.1;
} }

View file

@ -3,6 +3,7 @@ import {UIElement} from "../UI/UIElement";
import {TagDependantUIElementConstructor} from "./UIElementConstructor"; import {TagDependantUIElementConstructor} from "./UIElementConstructor";
import {TagRenderingOptions} from "./TagRenderingOptions"; import {TagRenderingOptions} from "./TagRenderingOptions";
import Translation from "../UI/i18n/Translation"; import Translation from "../UI/i18n/Translation";
import {LayerConfigJson} from "./JSON/CustomLayoutFromJSON";
export interface Preset { export interface Preset {
tags: Tag[], tags: Tag[],
@ -127,4 +128,38 @@ export class LayerDefinition {
this.wayHandling = options.wayHandling ?? LayerDefinition.WAYHANDLING_DEFAULT; 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)
}
} }

View file

@ -0,0 +1,2 @@
{
}

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -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.", "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" "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": [ "language": [
"en", "en",
"nl" "nl"

View file

@ -167,8 +167,9 @@
"maintainer": "Pieter Vander Vennet", "maintainer": "Pieter Vander Vennet",
"title": "Open Toilet Map", "title": "Open Toilet Map",
"startLon": "3.2222", "startLon": "3.2222",
"widenFactor": 0.05,
"icon": "./assets/themes/toilets/toilets.svg", "icon": "./assets/themes/toilets/toilets.svg",
"description": "A map of public toilets", "description": "A map of public toilets",
"language": "en", "language": ["en"],
"name": "toilets" "name": "toilets"
} }

View file

@ -6,6 +6,7 @@ import {CustomLayoutFromJSON} from "../Customizations/JSON/CustomLayoutFromJSON"
import {And} from "../Logic/TagsFilter"; import {And} from "../Logic/TagsFilter";
import Translation from "../UI/i18n/Translation"; import Translation from "../UI/i18n/Translation";
import T from "./TestHelper"; import T from "./TestHelper";
import {Artwork} from "../Customizations/Layers/Artwork";
new T([ new T([
@ -21,7 +22,7 @@ new T([
const tags = CustomLayoutFromJSON.TagsFromJson("highway~=residential|tertiary"); const tags = CustomLayoutFromJSON.TagsFromJson("highway~=residential|tertiary");
equal(""+tags[0].value, ""+/residential|tertiary/); equal(""+tags[0].value, ""+/residential|tertiary/);
console.log(tags[0].asOverpass()); console.log(tags[0].asOverpass());
} }
], ],
["Tag replacement works in translation", () => { ["Tag replacement works in translation", () => {
@ -30,5 +31,9 @@ new T([
}).replace("{key}", "value"); }).replace("{key}", "value");
equal(tr.txt, "Test value abc"); equal(tr.txt, "Test value abc");
}],
["JSONify artwork layer", () => {
const a = new Artwork();
console.log(a.ToJson())
}] }]
]); ]);