First steps for a decent custom theme generator

This commit is contained in:
Pieter Vander Vennet 2020-08-31 02:59:47 +02:00
parent a57b7d93fa
commit 2052976909
82 changed files with 1880 additions and 1311 deletions

View file

@ -13,10 +13,31 @@ import Translations from "../../UI/i18n/Translations";
import Combine from "../../UI/Base/Combine";
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
import {ImageCarouselConstructor} from "../../UI/Image/ImageCarousel";
import * as drinkingWater from "../../assets/layers/drinking_water/drinking_water.json";
import * as ghostbikes from "../../assets/layers/ghost_bike/ghost_bike.json"
import * as viewpoint from "../../assets/layers/viewpoint/viewpoint.json"
import {Utils} from "../../Utils";
export class FromJSON {
public static sharedLayers: Map<string, LayerDefinition> = FromJSON.getSharedLayers();
private static getSharedLayers() {
const sharedLayers = new Map<string, LayerDefinition>();
const sharedLayersList = [
FromJSON.Layer(drinkingWater),
FromJSON.Layer(ghostbikes),
FromJSON.Layer(viewpoint),
];
for (const layer of sharedLayersList) {
sharedLayers.set(layer.id, layer);
}
return sharedLayers;
}
public static FromBase64(layoutFromBase64: string): Layout {
return FromJSON.LayoutFromJSON(JSON.parse(atob(layoutFromBase64)));
@ -139,19 +160,27 @@ export class FromJSON {
{
k: FromJSON.Tag(mapping.if),
txt: FromJSON.Translation(mapping.then),
hideInAnswer: mapping.hideInAnswer
hideInAnswer: mapping.hideInAnswer
})
);
return new TagRenderingOptions({
let rendering = new TagRenderingOptions({
question: FromJSON.Translation(json.question),
freeform: freeform,
mappings: mappings
});
if (json.condition) {
console.log("Applying confition ", json.condition)
return rendering.OnlyShowIf(FromJSON.Tag(json.condition));
}
return rendering;
}
public static SimpleTag(json: string): Tag {
const tag = json.split("=");
const tag = Utils.SplitFirst(json, "=");
return new Tag(tag[0], tag[1]);
}
@ -159,35 +188,39 @@ export class FromJSON {
if (typeof (json) == "string") {
const tag = json as string;
if (tag.indexOf("!~") >= 0) {
const split = tag.split("!~");
if(split[1] == "*"){
const split = Utils.SplitFirst(tag, "!~");
if (split[1] === "*") {
split[1] = ".*"
}
console.log(split)
return new RegexTag(
new RegExp(split[0]),
new RegExp(split[1]),
split[0],
new RegExp("^" + split[1] + "$"),
true
);
}
if (tag.indexOf("!=") >= 0) {
const split = tag.split("!=");
const split = Utils.SplitFirst(tag, "!=");
if (split[1] === "*") {
split[1] = ".*"
}
return new RegexTag(
new RegExp(split[0]),
new RegExp(split[1]),
split[0],
new RegExp("^" + split[1] + "$"),
true
);
}
if (tag.indexOf("~") >= 0) {
const split = tag.split("~");
if(split[1] == "*"){
const split = Utils.SplitFirst(tag, "~");
if (split[1] === "*") {
split[1] = ".*"
}
return new RegexTag(
new RegExp("^"+split[0]+"$"),
new RegExp("^"+split[1]+"$")
split[0],
new RegExp("^" + split[1] + "$")
);
}
const split = tag.split("=");
const split = Utils.SplitFirst(tag, "=");
return new Tag(split[0], split[1])
}
if (json.and !== undefined) {
@ -208,11 +241,23 @@ export class FromJSON {
}
}
public static Layer(json: LayerConfigJson): LayerDefinition {
console.log("Parsing ",json.name);
public static Layer(json: LayerConfigJson | string): LayerDefinition {
if (typeof (json) === "string") {
const cached = FromJSON.sharedLayers.get(json);
if (cached) {
return cached;
}
throw "Layer not yet loaded..."
}
console.log("Parsing ", json.name);
const tr = FromJSON.Translation;
const overpassTags = FromJSON.Tag(json.overpassTags);
const icon = FromJSON.TagRenderingWithDefault(json.icon, "layericon", "./assets/bug.svg");
const iconSize = FromJSON.TagRenderingWithDefault(json.iconSize, "iconSize", "40,40,center");
const color = FromJSON.TagRenderingWithDefault(json.color, "layercolor", "#0000ff");
const width = FromJSON.TagRenderingWithDefault(json.width, "layerwidth", "10");
const renderTags = {"id": "node/-1"}
@ -225,11 +270,38 @@ export class FromJSON {
}) ?? [];
function style(tags) {
const iconSizeStr = iconSize.GetContent(tags).txt.split(",");
const iconwidth = Number(iconSizeStr[0]);
const iconheight = Number(iconSizeStr[1]);
const iconmode = iconSizeStr[2];
const iconAnchor = [iconwidth / 2, iconheight / 2] // x, y
// If iconAnchor is set to [0,0], then the top-left of the icon will be placed at the geographical location
if (iconmode.indexOf("left") >= 0) {
iconAnchor[0] = 0;
}
if (iconmode.indexOf("right") >= 0) {
iconAnchor[0] = iconwidth;
}
if (iconmode.indexOf("top") >= 0) {
iconAnchor[1] = 0;
}
if (iconmode.indexOf("bottom") >= 0) {
iconAnchor[1] = iconheight;
}
// the anchor is always set from the center of the point
// x, y with x going right and y going down if the values are bigger
const popupAnchor = [0, -iconAnchor[1]+3];
return {
color: color.GetContent(tags).txt,
weight: width.GetContent(tags).txt,
icon: {
iconUrl: icon.GetContent(tags).txt
iconUrl: icon.GetContent(tags).txt,
iconSize: [iconwidth, iconheight],
popupAnchor: popupAnchor,
iconAnchor: iconAnchor
},
}
}

View file

@ -46,6 +46,13 @@ export interface LayerConfigJson {
* Note that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.
*/
icon?: string | TagRenderingConfigJson;
/**
* A string containing "width,height" or "width,height,anchorpoint" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...
* Default is '40,40,center'
*/
iconSize?: string | TagRenderingConfigJson;
/**
* The color for way-elements
*/
@ -67,8 +74,8 @@ export interface LayerConfigJson {
* Presets for this layer
*/
presets?: {
tags: string[],
title: string | any,
tags: string[],
description?: string | any,
}[],

View file

@ -83,12 +83,12 @@ export interface LayoutConfigJson {
* In order to prevent them to do too much damage, all the overpass-tags of the layers are taken and combined as OR.
* These tag renderings will only show up if the object matches this filter.
*/
roamingRenderings?: TagRenderingConfigJson[],
roamingRenderings?: (TagRenderingConfigJson | string)[],
/**
* The layers to display
*/
layers: LayerConfigJson[],
layers: (LayerConfigJson | string)[],

View file

@ -1,14 +0,0 @@
/**
* Read a tagconfig and converts it into a TagsFilter value
*/
import {AndOrTagConfigJson} from "./TagConfigJson";
export default class TagConfig {
public static fromJson(json: any): TagConfig {
const config: AndOrTagConfigJson = json;
return config;
}
}