More work on the theme generator
This commit is contained in:
parent
0f433d026a
commit
1625b21138
7 changed files with 74 additions and 31 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
2
assets/themes/artwork/artwork.json
Normal file
2
assets/themes/artwork/artwork.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
{
|
||||||
|
}
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -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())
|
||||||
}]
|
}]
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in a new issue