forked from MapComplete/MapComplete
		
	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([
 | 
				
			||||||
| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue