allow reuse of filters, update to artwork theme

This commit is contained in:
pietervdvn 2022-09-14 16:29:41 +02:00
parent a1a12e6f38
commit 585dbb4587
8 changed files with 221 additions and 119 deletions

View file

@ -1,23 +1,65 @@
import {
Concat,
Conversion,
DesugaringContext,
DesugaringStep,
Each,
FirstOf,
Fuse,
On,
SetDefault,
} from "./Conversion"
import { LayerConfigJson } from "../Json/LayerConfigJson"
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
import { Utils } from "../../../Utils"
import {Concat, Conversion, DesugaringContext, DesugaringStep, Each, FirstOf, Fuse, On, SetDefault,} from "./Conversion"
import {LayerConfigJson} from "../Json/LayerConfigJson"
import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"
import {Utils} from "../../../Utils"
import RewritableConfigJson from "../Json/RewritableConfigJson"
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
import Translations from "../../../UI/i18n/Translations"
import { Translation } from "../../../UI/i18n/Translation"
import {Translation} from "../../../UI/i18n/Translation"
import * as tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json"
import { AddContextToTranslations } from "./AddContextToTranslations"
import {AddContextToTranslations} from "./AddContextToTranslations"
import FilterConfigJson from "../Json/FilterConfigJson";
import * as predifined_filters from "../../../assets/layers/filters/filters.json"
class ExpandFilter extends DesugaringStep<LayerConfigJson>{
private static load_filters(): Map<string, FilterConfigJson>{
let filters = new Map<string, FilterConfigJson>();
for (const filter of (<FilterConfigJson[]>predifined_filters.filter)) {
filters.set(filter.id, filter)
}
return filters;
}
private static readonly predefinedFilters = ExpandFilter.load_filters();
constructor() {
super("Expands filters: replaces a shorthand by the value found in 'filters.json'", ["filter"], "ExpandFilter");
}
convert(json: LayerConfigJson, context: string): { result: LayerConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } {
if(json.filter === undefined || json.filter === null){
return {result: json} // Nothing to change here
}
if( json.filter["sameAs"] !== undefined){
return {result: json} // Nothing to change here
}
const newFilters : FilterConfigJson[] = []
const errors :string[]= []
for (const filter of (<(FilterConfigJson|string)[]> json.filter)) {
if (typeof filter !== "string") {
newFilters.push(filter)
continue
}
// Search for the filter:
const found = ExpandFilter.predefinedFilters.get(filter)
if(found === undefined){
const suggestions = Utils.sortedByLevenshteinDistance(filter, Array.from(ExpandFilter.predefinedFilters.keys()), t => t)
const err = context+".filter: while searching for predifined filter "+filter+": this filter is not found. Perhaps you meant one of: "+suggestions
errors.push(err)
}
newFilters.push(found)
}
return {result: {
...json, filter: newFilters
}, errors};
}
}
class ExpandTagRendering extends Conversion<
string | TagRenderingConfigJson | { builtin: string | string[]; override: any },
@ -178,7 +220,7 @@ class ExpandTagRendering extends Conversion<
if (lookup === undefined) {
let candidates = Array.from(state.tagRenderings.keys())
if (name.indexOf(".") > 0) {
const [layerName, search] = name.split(".")
const [layerName] = name.split(".")
let layer = state.sharedLayers.get(layerName)
if (layerName === this._self.id) {
layer = this._self
@ -699,7 +741,8 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
)
),
new SetDefault("titleIcons", ["defaults"]),
new On("titleIcons", (layer) => new Concat(new ExpandTagRendering(state, layer)))
new On("titleIcons", (layer) => new Concat(new ExpandTagRendering(state, layer))),
new ExpandFilter()
)
}
}

View file

@ -316,9 +316,10 @@ export interface LayerConfigJson {
)[]
/**
* All the extra questions for filtering
* All the extra questions for filtering.
* If a string is given, mapComplete will search in 'filters.json' for the appropriate filter
*/
filter?: FilterConfigJson[] | { sameAs: string }
filter?: (FilterConfigJson | string)[] | { sameAs: string }
/**
* This block defines under what circumstances the delete dialog is shown for objects of this layer.

View file

@ -267,6 +267,9 @@ export default class TagRenderingConfig {
if (this.freeform.key === "wikidata" && txt.indexOf("{wikipedia()") >= 0) {
continue
}
if (this.freeform.type === "wikidata" && txt.indexOf(`{wikidata_label(${this.freeform.key})`) >= 0) {
continue
}
throw `${context}: The rendering for language ${ln} does not contain the freeform key {${this.freeform.key}}. This is a bug, as this rendering should show exactly this freeform key!\nThe rendering is ${txt} `
}
}

View file

@ -407,10 +407,38 @@
"es": "Cerámica",
"da": "flisebeklædning"
}
},
{
"if": "artwork_type=woodcarving",
"then": {
"nl": "Houtsculptuur",
"en": "Woodcarving"
}
}
],
"id": "artwork-artwork_type"
},
{
"id": "artwork-artist-wikidata",
"render": {
"en": "This artwork was made by <b>{wikidata_label(artist:wikidata)}</b>"
},
"question": {
"en": "Who made this artwork?"
},
"freeform": {
"key": "artist:wikidata",
"type": "wikidata",
"helperArgs": [
{
"key": "artist_name",
"instanceOf": [
"Q5"
]
}
]
}
},
{
"question": {
"en": "Which artist created this?",
@ -449,6 +477,7 @@
"freeform": {
"key": "artist_name"
},
"condition": "artist:wikidata=",
"id": "artwork-artist_name"
},
{
@ -491,7 +520,21 @@
},
"id": "artwork-website"
},
"wikipedia"
"wikipedia",
{
"id": "artwork_subject",
"condition": "subject:wikidata~*",
"question": {
"en": "What does this artwork depict?"
},
"freeform": {
"key": "subject:wikidata",
"type": "wikidata"
},
"render": {
"en": "This artwork depicts {wikidata_label(subject:wikidata)}{wikipedia(subject:wikidata)}"
}
}
],
"deletion": {
"softDeletionTags": {
@ -524,5 +567,6 @@
"render": "10"
}
}
]
],
"filter": ["has_image"]
}

View file

@ -277,24 +277,9 @@
"reviews"
],
"filter": [
{
"id": "opened-now",
"options": [
{
"question": {
"en": "Opened now",
"nl": "Nu geopend",
"de": "Derzeit geöffnet",
"fr": "Ouvert maintenant",
"hu": "Most nyitva van",
"ca": "Obert ara",
"es": "Abiert oahora",
"da": "Åbent nu"
},
"osmTags": "_isOpen=yes"
}
]
}
"open_now",
"accepts_cash",
"accepts_cards"
],
"deletion": {
"softDeletionTags": {
@ -362,4 +347,4 @@
"da": "Et lag med caféer og pubber, hvor man kan samles omkring en drink. Laget stiller nogle relevante spørgsmål",
"fr": "Une couche montrants les cafés et pubs où lon peut prendre un verre. Cette couche pose des questions y afférentes."
}
}
}

View file

@ -0,0 +1,95 @@
{
"id": "filters",
"description": "This layer acts as library for common filters",
"mapRendering": [
],
"source": {
"osmTags": "id~*"
},
"filter": [
{
"id":"open_now",
"options": [
{
"question": {
"en": "Opened now",
"nl": "Nu geopened",
"de": "Aktuell geöffnet",
"ca": "Obert ara",
"es": "Abierta ahora",
"fr": "Ouvert maintenant",
"hu": "Most nyitva van",
"da": "Åbent nu"
},
"osmTags": "_isOpen=yes"
}
]
},
{
"id": "accepts_cash",
"options": [
{
"osmTags": "payment:cash=yes",
"question": {
"en": "Accepts cash",
"de": "Akzeptiert Bargeld",
"nl": "Accepteert cash",
"es": "Acepta efectivo",
"fr": "Accepte les espèces"
}
}
]
},
{
"id": "accepts_cards",
"options": [
{
"osmTags": "payment:cards=yes",
"question": {
"en": "Accepts payment cards",
"de": "Akzeptiert Kartenzahlung",
"nl": "Accepteert betaalkaarten",
"es": "Acepta el pago por tarjeta",
"fr": "Accepte les cartes de paiement"
}
}
]
},
{
"id": "has_image",
"options": [
{
"question": "With and without images"
},
{
"question": {
"en": "Has at least one image"
},
"osmTags": {
"or": [
"image~*",
"image:0~*",
"image:1~*",
"image:2~*",
"image:3~*"
]
}
},
{
"question": {
"en": "Probably does not have an image"
},
"osmTags": {
"and": [
"image=",
"image:0=",
"image:1=",
"image:2=",
"image:3="
]
}
}
]
}
]
}

View file

@ -770,22 +770,7 @@
"reviews"
],
"filter": [
{
"id": "opened-now",
"options": [
{
"question": {
"en": "Opened now",
"nl": "Nu geopened",
"de": "Aktuell geöffnet",
"ca": "Obert ara",
"es": "Abierta ahora",
"fr": "Ouvert maintenant"
},
"osmTags": "_isOpen=yes"
}
]
},
"open_now",
{
"id": "vegetarian",
"options": [
@ -849,36 +834,8 @@
}
]
},
{
"id": "accepts-cash",
"options": [
{
"osmTags": "payment:cash=yes",
"question": {
"en": "Accepts cash",
"de": "Akzeptiert Bargeld",
"es": "Acepta efectivo",
"nl": "Accepteert cash",
"fr": "Accepte les paiements en espèces"
}
}
]
},
{
"id": "accepts-cards",
"options": [
{
"osmTags": "payment:cards=yes",
"question": {
"en": "Accepts payment cards",
"de": "Akzeptiert Kartenzahlung",
"es": "Acepta tarjetas de pago",
"nl": "Accepteert betaalkaarten",
"fr": "Accepte les cartes de paiement"
}
}
]
}
"accepts_cash",
"accepts_cards"
],
"deletion": {
"nonDeleteMappings": [
@ -979,4 +936,4 @@
"es": "Una capa que muestra restaurantes y facilidades de comida rápida",
"fr": "Un claque montrant les restaurants et les endroits de nourriture rapide (avec un rendu spécial pour les friteries)"
}
}
}

View file

@ -295,6 +295,7 @@
}
],
"filter": [
"open_now",
{
"id": "shop-type",
"options": [
@ -337,35 +338,8 @@
}
]
},
{
"id": "accepts-cash",
"options": [
{
"osmTags": "payment:cash=yes",
"question": {
"en": "Accepts cash",
"de": "Akzeptiert Bargeld",
"nl": "Accepteert cash",
"es": "Acepta efectivo",
"fr": "Accepte les espèces"
}
}
]
},
{
"id": "accepts-cards",
"options": [
{
"osmTags": "payment:cards=yes",
"question": {
"en": "Accepts payment cards",
"de": "Akzeptiert Kartenzahlung",
"nl": "Accepteert betaalkaarten",
"es": "Acepta el pago por tarjeta",
"fr": "Accepte les cartes de paiement"
}
}
]
}
"accepts_cash",
"accepts_cards"
]
}
}