From eb6093dd9ff810cb9128d1bfa2c9d2c5243d7ab3 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 9 Mar 2023 14:45:36 +0100 Subject: [PATCH] feature(themeconfig): Make filters reusable from builtin layers --- Models/ThemeConfig/Conversion/PrepareLayer.ts | 35 +++++++++++++++++-- Models/ThemeConfig/Json/LayerConfigJson.ts | 2 +- .../toilet_at_amenity/toilet_at_amenity.json | 17 +-------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/Models/ThemeConfig/Conversion/PrepareLayer.ts b/Models/ThemeConfig/Conversion/PrepareLayer.ts index 5ca0f007af..fe8c483c88 100644 --- a/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -23,16 +23,20 @@ import predifined_filters from "../../../assets/layers/filters/filters.json" import { TagConfigJson } from "../Json/TagConfigJson" import PointRenderingConfigJson from "../Json/PointRenderingConfigJson" import LineRenderingConfigJson from "../Json/LineRenderingConfigJson" +import { type } from "os" +import exp from "constants" class ExpandFilter extends DesugaringStep { private static readonly predefinedFilters = ExpandFilter.load_filters() + private _state: DesugaringContext - constructor() { + constructor(state: DesugaringContext) { super( - "Expands filters: replaces a shorthand by the value found in 'filters.json'", + "Expands filters: replaces a shorthand by the value found in 'filters.json'. If the string is formatted 'layername.filtername, it will be looked up into that layer instead", ["filter"], "ExpandFilter" ) + this._state = state } private static load_filters(): Map { @@ -62,6 +66,31 @@ class ExpandFilter extends DesugaringStep { newFilters.push(filter) continue } + if (filter.indexOf(".") > 0) { + if (this._state.sharedLayers.size > 0) { + const split = filter.split(".") + if (split.length > 2) { + errors.push( + context + + ": invalid filter name: " + + filter + + ", expected `layername.filterid`" + ) + } + const layer = this._state.sharedLayers.get(split[0]) + if (layer === undefined) { + errors.push(context + ": layer '" + split[0] + "' not found") + } + const expectedId = split[1] + const expandedFilter = (<(FilterConfigJson | string)[]>layer.filter).find( + (f) => typeof f !== "string" && f.id === expectedId + ) + newFilters.push(expandedFilter) + } else { + // This is a bootstrapping-run, we can safely ignore this + } + continue + } // Search for the filter: const found = ExpandFilter.predefinedFilters.get(filter) if (found === undefined) { @@ -889,7 +918,7 @@ export class PrepareLayer extends Fuse { (layer) => new Concat(new ExpandTagRendering(state, layer, { noHardcodedStrings: true })) ), - new ExpandFilter() + new ExpandFilter(state) ) } } diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index fd80dc4b50..bbbdf0d171 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -317,7 +317,7 @@ export interface LayerConfigJson { /** * All the extra questions for filtering. - * If a string is given, mapComplete will search in 'filters.json' for the appropriate filter + * If a string is given, mapComplete will search in 'filters.json' for the appropriate filter or will try to parse it as `layername.filterid` and us that one */ filter?: (FilterConfigJson | string)[] | { sameAs: string } diff --git a/assets/layers/toilet_at_amenity/toilet_at_amenity.json b/assets/layers/toilet_at_amenity/toilet_at_amenity.json index adf8e80197..b4e05b46ba 100644 --- a/assets/layers/toilet_at_amenity/toilet_at_amenity.json +++ b/assets/layers/toilet_at_amenity/toilet_at_amenity.json @@ -299,22 +299,7 @@ } ] }, - { - "id": "changing_table", - "options": [ - { - "question": { - "en": "Has a changing table", - "nl": "Heeft een luiertafel", - "de": "Mit Wickeltisch", - "es": "Tiene un cambiador", - "fr": "A une table à langer", - "da": "Har et puslebord" - }, - "osmTags": "changing_table=yes" - } - ] - }, + "toilet.changing_table", { "id": "free", "options": [