forked from MapComplete/MapComplete
allow reuse of filters, update to artwork theme
This commit is contained in:
parent
a1a12e6f38
commit
585dbb4587
8 changed files with 221 additions and 119 deletions
|
@ -1,23 +1,65 @@
|
||||||
import {
|
import {Concat, Conversion, DesugaringContext, DesugaringStep, Each, FirstOf, Fuse, On, SetDefault,} from "./Conversion"
|
||||||
Concat,
|
import {LayerConfigJson} from "../Json/LayerConfigJson"
|
||||||
Conversion,
|
import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"
|
||||||
DesugaringContext,
|
import {Utils} from "../../../Utils"
|
||||||
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 RewritableConfigJson from "../Json/RewritableConfigJson"
|
||||||
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||||
import Translations from "../../../UI/i18n/Translations"
|
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 * 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<
|
class ExpandTagRendering extends Conversion<
|
||||||
string | TagRenderingConfigJson | { builtin: string | string[]; override: any },
|
string | TagRenderingConfigJson | { builtin: string | string[]; override: any },
|
||||||
|
@ -178,7 +220,7 @@ class ExpandTagRendering extends Conversion<
|
||||||
if (lookup === undefined) {
|
if (lookup === undefined) {
|
||||||
let candidates = Array.from(state.tagRenderings.keys())
|
let candidates = Array.from(state.tagRenderings.keys())
|
||||||
if (name.indexOf(".") > 0) {
|
if (name.indexOf(".") > 0) {
|
||||||
const [layerName, search] = name.split(".")
|
const [layerName] = name.split(".")
|
||||||
let layer = state.sharedLayers.get(layerName)
|
let layer = state.sharedLayers.get(layerName)
|
||||||
if (layerName === this._self.id) {
|
if (layerName === this._self.id) {
|
||||||
layer = this._self
|
layer = this._self
|
||||||
|
@ -699,7 +741,8 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new SetDefault("titleIcons", ["defaults"]),
|
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()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* This block defines under what circumstances the delete dialog is shown for objects of this layer.
|
||||||
|
|
|
@ -267,6 +267,9 @@ export default class TagRenderingConfig {
|
||||||
if (this.freeform.key === "wikidata" && txt.indexOf("{wikipedia()") >= 0) {
|
if (this.freeform.key === "wikidata" && txt.indexOf("{wikipedia()") >= 0) {
|
||||||
continue
|
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} `
|
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} `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,10 +407,38 @@
|
||||||
"es": "Cerámica",
|
"es": "Cerámica",
|
||||||
"da": "flisebeklædning"
|
"da": "flisebeklædning"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "artwork_type=woodcarving",
|
||||||
|
"then": {
|
||||||
|
"nl": "Houtsculptuur",
|
||||||
|
"en": "Woodcarving"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": "artwork-artwork_type"
|
"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": {
|
"question": {
|
||||||
"en": "Which artist created this?",
|
"en": "Which artist created this?",
|
||||||
|
@ -449,6 +477,7 @@
|
||||||
"freeform": {
|
"freeform": {
|
||||||
"key": "artist_name"
|
"key": "artist_name"
|
||||||
},
|
},
|
||||||
|
"condition": "artist:wikidata=",
|
||||||
"id": "artwork-artist_name"
|
"id": "artwork-artist_name"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -491,7 +520,21 @@
|
||||||
},
|
},
|
||||||
"id": "artwork-website"
|
"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": {
|
"deletion": {
|
||||||
"softDeletionTags": {
|
"softDeletionTags": {
|
||||||
|
@ -524,5 +567,6 @@
|
||||||
"render": "10"
|
"render": "10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"filter": ["has_image"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,24 +277,9 @@
|
||||||
"reviews"
|
"reviews"
|
||||||
],
|
],
|
||||||
"filter": [
|
"filter": [
|
||||||
{
|
"open_now",
|
||||||
"id": "opened-now",
|
"accepts_cash",
|
||||||
"options": [
|
"accepts_cards"
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"deletion": {
|
"deletion": {
|
||||||
"softDeletionTags": {
|
"softDeletionTags": {
|
||||||
|
|
95
assets/layers/filters/filters.json
Normal file
95
assets/layers/filters/filters.json
Normal 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="
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -770,22 +770,7 @@
|
||||||
"reviews"
|
"reviews"
|
||||||
],
|
],
|
||||||
"filter": [
|
"filter": [
|
||||||
{
|
"open_now",
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "vegetarian",
|
"id": "vegetarian",
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -849,36 +834,8 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
"accepts_cash",
|
||||||
"id": "accepts-cash",
|
"accepts_cards"
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"deletion": {
|
"deletion": {
|
||||||
"nonDeleteMappings": [
|
"nonDeleteMappings": [
|
||||||
|
|
|
@ -295,6 +295,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filter": [
|
"filter": [
|
||||||
|
"open_now",
|
||||||
{
|
{
|
||||||
"id": "shop-type",
|
"id": "shop-type",
|
||||||
"options": [
|
"options": [
|
||||||
|
@ -337,35 +338,8 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
"accepts_cash",
|
||||||
"id": "accepts-cash",
|
"accepts_cards"
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in a new issue