Themes(cafe_pub, toilets): add toilet information to pubs; forward wheelchair accessibility information to 'toilet_at_amenity'

This commit is contained in:
Pieter Vander Vennet 2025-04-22 01:20:57 +02:00
parent 7a0eed35e3
commit 455b2c641c
9 changed files with 75 additions and 118 deletions

View file

@ -413,10 +413,9 @@
"service:electricity", "service:electricity",
"seating", "seating",
"dog-access", "dog-access",
"internet", "internet-all",
"internet-fee", "reviews",
"internet-ssid", "toilet_at_amenity_lib.all"
"reviews"
], ],
"filter": [ "filter": [
"open_now", "open_now",

View file

@ -1158,12 +1158,23 @@
] ]
} }
}, },
{
"builtin":
"description", "description",
"override": {
"labels": [
"amenity-no-prefix",
"no-prefix",
"relevant-questions"
]
}
},
{ {
"id": "wheelchair-group", "id": "wheelchair-group",
"labels": [ "labels": [
"relevant-questions", "relevant-questions",
"prefixed" "prefixed",
"amenity-prefixed"
], ],
"render": { "render": {
"special": { "special": {
@ -1179,7 +1190,8 @@
"relevant-questions", "relevant-questions",
"wheelchair", "wheelchair",
"hidden", "hidden",
"no-prefix" "no-prefix",
"amenity-no-prefix"
], ],
"question": { "question": {
"en": "Is there a dedicated toilet for wheelchair users?", "en": "Is there a dedicated toilet for wheelchair users?",
@ -1190,7 +1202,8 @@
"da": "Er der et særligt toilet til kørestolsbrugere?", "da": "Er der et særligt toilet til kørestolsbrugere?",
"ca": "Hi ha un lavabo específic per a usuaris amb cadira de rodes?", "ca": "Hi ha un lavabo específic per a usuaris amb cadira de rodes?",
"cs": "Je zde vyhrazená toaleta pro vozíčkáře?", "cs": "Je zde vyhrazená toaleta pro vozíčkáře?",
"es": "¿Hay un baño dedicado para usuarios de sillas de ruedas?" "es": "¿Hay un baño dedicado para usuarios de sillas de ruedas?",
"sl": "Ali je tu stranišče namenjeno invalidom na vozičku?"
}, },
"mappings": [ "mappings": [
{ {
@ -1219,7 +1232,8 @@
"es": "Sin acceso para sillas de ruedas", "es": "Sin acceso para sillas de ruedas",
"da": "Ingen kørestolsadgang", "da": "Ingen kørestolsadgang",
"ca": "Sense accés per a cadires de rodes", "ca": "Sense accés per a cadires de rodes",
"cs": "Žádný bezbariérový přístup" "cs": "Žádný bezbariérový přístup",
"sl": "Ni dostopno invalidom na vozičku"
} }
}, },
{ {
@ -1253,7 +1267,8 @@
"wheelchair", "wheelchair",
"hidden", "hidden",
"relevant-questions", "relevant-questions",
"prefixed" "prefixed",
"amenity-prefixed"
], ],
"render": { "render": {
"special": { "special": {
@ -1279,7 +1294,8 @@
"wheelchair", "wheelchair",
"hidden", "hidden",
"relevant-questions", "relevant-questions",
"prefixed" "prefixed",
"amenity-prefixed"
], ],
"render": { "render": {
"special": { "special": {
@ -1297,7 +1313,8 @@
"labels": [ "labels": [
"hidden", "hidden",
"relevant-questions", "relevant-questions",
"prefixed" "prefixed",
"amenity-prefixed"
], ],
"render": { "render": {
"en": "Wheelchair accessible toilet", "en": "Wheelchair accessible toilet",
@ -1332,7 +1349,7 @@
] ]
}, },
{ {
"id": "wheelchair-access", "id": "toilet-wheelchair-access",
"question": { "question": {
"en": "Is the wheelchair-accessible toilet locked?", "en": "Is the wheelchair-accessible toilet locked?",
"nl": "Is de rolstoeltoegankelijke toilet op slot?" "nl": "Is de rolstoeltoegankelijke toilet op slot?"
@ -1359,7 +1376,8 @@
"hidden", "hidden",
"wheelchair", "wheelchair",
"relevant-questions", "relevant-questions",
"prefixed" "prefixed",
"amenity-prefixed"
], ],
"mappings": [ "mappings": [
{ {
@ -1477,7 +1495,8 @@
"labels": [ "labels": [
"wheelchair", "wheelchair",
"hidden", "hidden",
"relevant-questions" "relevant-questions",
"amenity-prefixed"
], ],
"render": { "render": {
"special": { "special": {
@ -1492,7 +1511,8 @@
"labels+": [ "labels+": [
"hidden", "hidden",
"prefixed", "prefixed",
"adult-changing-table" "adult-changing-table",
"amenity-prefixed"
], ],
"condition": { "condition": {
"and": [ "and": [
@ -1508,7 +1528,8 @@
"prefixed", "prefixed",
"hidden", "hidden",
"relevant-questions", "relevant-questions",
"adult-changing-table" "adult-changing-table",
"amenity-prefixed"
], ],
"question": { "question": {
"en": "Does this toilet have an adult changing table?", "en": "Does this toilet have an adult changing table?",
@ -1538,7 +1559,8 @@
"labels+": [ "labels+": [
"hidden", "hidden",
"prefixed", "prefixed",
"adult-changing-table" "adult-changing-table",
"amenity-prefixed"
], ],
"condition": { "condition": {
"and+": [ "and+": [
@ -1553,7 +1575,8 @@
"labels": [ "labels": [
"hidden", "hidden",
"relevant-questions", "relevant-questions",
"adult-changing-table" "adult-changing-table",
"amenity-prefixed"
], ],
"render": { "render": {
"special": { "special": {

View file

@ -188,93 +188,6 @@
"relevant_questions" "relevant_questions"
] ]
} }
},
{
"id": "toilets-wheelchair",
"labels": [
"wheelchair",
"hidden"
],
"question": {
"en": "Is there a dedicated toilet for wheelchair users?",
"de": "Können Rollstuhlfahrer die Toilette benutzen?",
"fr": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?",
"nl": "Is er een rolstoeltoegankelijke toilet voorzien?",
"it": "C'è un WC riservato alle persone in sedia a rotelle?",
"da": "Er der et særligt toilet til kørestolsbrugere?",
"ca": "Hi ha un lavabo específic per a usuaris amb cadira de rodes?",
"cs": "Existuje vyhrazená toaleta pro vozíčkáře?",
"sl": "Ali je tu stranišče namenjeno invalidom na vozičku?",
"es": "¿Hay un baño dedicado para usuarios de sillas de ruedas?"
},
"mappings": [
{
"then": {
"en": "There is a dedicated toilet for wheelchair users",
"de": "Rollstuhlfahrer können die Toilette benutzen",
"fr": "Il y a des toilettes réservées pour les personnes à mobilité réduite",
"nl": "Er is een toilet voor rolstoelgebruikers",
"it": "C'è un WC riservato alle persone in sedia a rotelle",
"es": "Hay un baño dedicado para usuarios de sillas de ruedas",
"da": "Der er et særligt toilet til kørestolsbrugere",
"ca": "Hi ha un lavabo dedicat per a usuaris amb cadira de rodes",
"cs": "K dispozici je vyhrazená toaleta pro vozíčkáře"
},
"if": "toilets:wheelchair=yes"
},
{
"if": "toilets:wheelchair=no",
"then": {
"en": "No wheelchair access",
"de": "Rollstuhlfahrer können die Toilette nicht benutzen",
"fr": "Non accessible aux personnes à mobilité réduite",
"nl": "Niet toegankelijk voor rolstoelgebruikers",
"it": "Non accessibile in sedia a rotelle",
"ru": "Недоступно пользователям кресел-колясок",
"es": "Sin acceso para sillas de ruedas",
"da": "Ingen kørestolsadgang",
"ca": "Sense accés per a cadires de rodes",
"cs": "Žádný bezbariérový přístup",
"sl": "Ni dostopno invalidom na vozičku"
}
},
{
"if": "toilets:wheelchair=designated",
"then": {
"en": "There is only a dedicated toilet for wheelchair users",
"nl": "Er is alleen een toilet voor rolstoelgebruikers",
"de": "Es gibt nur eine barrierefreie Toilette für Rollstuhlfahrer",
"da": "Der er kun et særligt toilet til kørestolsbrugere",
"ca": "Sols hi ha un lavabo per a usuaris amb cadira de rodes",
"cs": "K dispozici je pouze vyhrazená toaleta pro vozíčkáře",
"es": "Solo hay un baño dedicado para usuarios de sillas de ruedas"
}
}
]
},
{
"id": "questions-wheelchair",
"labels": [
"wheelchair",
"hidden"
],
"render": {
"special": {
"type": "questions",
"labels": "wheelchair",
"show_all": "yes"
}
}
},
{
"builtin": "description",
"override": {
"render": "{toilets:description}",
"freeform": {
"key": "toilets:description",
"type": "string"
}
}
} }
], ],
"filter": [ "filter": [

View file

@ -12,7 +12,8 @@
"special": { "special": {
"type": "group", "type": "group",
"header": "grouptitle", "header": "grouptitle",
"labels": "toilet-questions" "labels": "toilet-questions",
"blacklist": "wheelchair;wheelchair-title;adult-changing-table"
} }
} }
}, },

View file

@ -270,7 +270,7 @@ class LayerBuilder extends Conversion<object, Map<string, LayerConfigJson>> {
for (let i = 0; i < level.ids.length; i++) { for (let i = 0; i < level.ids.length; i++) {
const id = level.ids[i] const id = level.ids[i]
ScriptUtils.erasableLog(`Building level ${level.level}: validating layer ${i + 1}/${level.ids.length}: ${id}`) ScriptUtils.erasableLog(`Building level ${i}: validating layer ${i + 1}/${level.ids.length}: ${id}`)
if (id === "questions") { if (id === "questions") {
continue continue
} }
@ -362,7 +362,6 @@ class LayerOverviewUtils extends Script {
for (const path of sourcefile) { for (const path of sourcefile) {
const hasChange = statSync(path).mtime > targetModified const hasChange = statSync(path).mtime > targetModified
if (hasChange) { if (hasChange) {
console.log("File ", targetfile, " should be updated as ", path, "has been changed")
return true return true
} }
} }
@ -751,8 +750,13 @@ class LayerOverviewUtils extends Script {
for (let i = 0; i < allPaths.length; i++) { for (let i = 0; i < allPaths.length; i++) {
const path = allPaths[i] const path = allPaths[i]
ScriptUtils.erasableLog(`Parsing layerConfig ${i + 1}/${allPaths.length}: ${path} `) ScriptUtils.erasableLog(`Parsing layerConfig ${i + 1}/${allPaths.length}: ${path} `)
const data = JSON.parse(readFileSync(path, "utf8")) try {
const data = JSON.parse(readFileSync(path, "utf8"))
results.push(data) results.push(data)
} catch (e) {
throw "Could not parse layer file " + path
}
} }
@ -776,7 +780,10 @@ class LayerOverviewUtils extends Script {
const layerState = new Map<string, "clean" | "dirty" | "changed">() const layerState = new Map<string, "clean" | "dirty" | "changed">()
console.log("# BUILD PLAN\n\n") console.log("# BUILD PLAN\n\n")
for (const levelInfo of levels) { for (const levelInfo of levels) {
console.log(`## LEVEL ${levelInfo.level}${levelInfo.loop ? " (LOOP)" : ""}`) if (levelInfo.loop) {
console.log(`(LOOP)`)
}
let allClean = true
for (const id of levelInfo.ids) { for (const id of levelInfo.ids) {
const deps = dependencyGraph.get(id) ?? [] const deps = dependencyGraph.get(id) ?? []
const dirtyDeps = deps.filter(dep => { const dirtyDeps = deps.filter(dep => {
@ -795,8 +802,6 @@ class LayerOverviewUtils extends Script {
if (dirtyDeps.length > 0) { if (dirtyDeps.length > 0) {
layerState.set(id, "dirty") layerState.set(id, "dirty")
} else { } else {
const sourcePath = `./assets/layers/${id}/${id}.json` const sourcePath = `./assets/layers/${id}/${id}.json`
const targetPath = `./public/assets/generated/layers/${id}.json` const targetPath = `./public/assets/generated/layers/${id}.json`
@ -809,7 +814,13 @@ class LayerOverviewUtils extends Script {
} }
} }
const state = layerState.get(id) const state = layerState.get(id)
if (state !== "clean") {
allClean = false
console.log(`- ${id} (${state}; ${dirtyDeps.map(dd => dd + "*").join(", ")})`) console.log(`- ${id} (${state}; ${dirtyDeps.map(dd => dd + "*").join(", ")})`)
}
}
if (allClean) {
console.log("\n")
} }
} }

View file

@ -1,7 +1,6 @@
import { LayerConfigJson } from "./Json/LayerConfigJson" import { LayerConfigJson } from "./Json/LayerConfigJson"
export interface LevelInfo { export interface LevelInfo {
level: number,
ids: string[], ids: string[],
loop?: boolean loop?: boolean
} }
@ -54,14 +53,11 @@ export class LayerConfigDependencyGraph {
public static buildLevels(dependsOn: Map<string, string[]>): LevelInfo[]{ public static buildLevels(dependsOn: Map<string, string[]>): LevelInfo[]{
const levels: LevelInfo[] = [] const levels: LevelInfo[] = []
let levelIndex = 0
const seenIds = new Set<string>() const seenIds = new Set<string>()
while (Array.from(dependsOn.keys()).length > 0) { while (Array.from(dependsOn.keys()).length > 0) {
const currentLevel: LevelInfo = { const currentLevel: LevelInfo = {
ids: <string[]>[], ids: <string[]>[],
level: levelIndex,
} }
levelIndex++
levels.push(currentLevel) levels.push(currentLevel)
for (const layerId of dependsOn.keys()) { for (const layerId of dependsOn.keys()) {
const dependencies = dependsOn.get(layerId) const dependencies = dependsOn.get(layerId)

View file

@ -13,6 +13,7 @@
export let selectedElement: Feature export let selectedElement: Feature
export let tags: UIEventSource<OsmTags> export let tags: UIEventSource<OsmTags>
export let labels: string[] export let labels: string[]
export let blacklist: string[]
export let header: string export let header: string
export let layer: LayerConfig export let layer: LayerConfig
@ -22,11 +23,15 @@
} }
let tagRenderings: TagRenderingConfig[] = [] let tagRenderings: TagRenderingConfig[] = []
let seenIds = new Set<string>() let seenIds = new Set<string>()
let blacklistSet = new Set(blacklist)
for (const label of labels) { for (const label of labels) {
for (const tr of layer.tagRenderings) { for (const tr of layer.tagRenderings) {
if (seenIds.has(tr.id)) { if (seenIds.has(tr.id)) {
continue continue
} }
if (blacklistSet.has(tr.id) || tr.labels.some(l => blacklistSet.has(l))) {
continue
}
if (label === tr.id || tr.labels.some((l) => l === label)) { if (label === tr.id || tr.labels.some((l) => l === label)) {
tagRenderings.push(tr) tagRenderings.push(tr)
seenIds.add(tr.id) seenIds.add(tr.id)

View file

@ -226,7 +226,9 @@
</button> </button>
{/if} {/if}
{#if $debug} {#if $debug}
Skipped questions are {Array.from($skippedQuestions).join(", ")} <span class="subtle">
DBG:Skipped questions are {Array.from($skippedQuestions).join(", ")}
</span>
{/if} {/if}
</div> </div>
</LoginToggle> </LoginToggle>

View file

@ -186,6 +186,11 @@ export default class TagrenderingManipulationSpecialVisualisations {
name: "labels", name: "labels",
doc: "A `;`-separated list of either identifiers or label names. All tagRenderings matching this value will be shown in the accordion", doc: "A `;`-separated list of either identifiers or label names. All tagRenderings matching this value will be shown in the accordion",
}, },
{
name: "blacklist",
required: false,
doc: "A `;`-separated list of either identifiers or label names. Matching tagrenderings will _not_ be included, even if they are in `labels`"
}
], ],
constr( constr(
state: SpecialVisualizationState, state: SpecialVisualizationState,
@ -194,8 +199,9 @@ export default class TagrenderingManipulationSpecialVisualisations {
selectedElement: Feature, selectedElement: Feature,
layer: LayerConfig layer: LayerConfig
): SvelteUIElement { ): SvelteUIElement {
const [header, labelsStr] = argument const [header, labelsStr, blacklistStr] = argument
const labels = labelsStr.split(";").map((x) => x.trim()) const labels = labelsStr.split(";").map((x) => x.trim())
const blacklist = blacklistStr?.split(";")?.map(x => x.trim()) ?? []
return new SvelteUIElement(GroupedView, { return new SvelteUIElement(GroupedView, {
state, state,
tags, tags,
@ -203,6 +209,7 @@ export default class TagrenderingManipulationSpecialVisualisations {
layer, layer,
header, header,
labels, labels,
blacklist
}) })
}, },
}, },