Feature: include (all) sign languages in the 'LanguageElement' special rendering

This commit is contained in:
Pieter Vander Vennet 2025-08-23 17:46:07 +02:00
parent 2a3e164669
commit fe31af4b15
7 changed files with 2251 additions and 8 deletions

View file

@ -18,7 +18,7 @@ interface value<T> {
} }
interface LanguageSpecResult { interface LanguageSpecResult {
directionalityLabel: value<string | "right-to-left" | "left-to-right"> directionalityLabel?: value<string | "right-to-left" | "left-to-right">
lang: value<string> lang: value<string>
code: value<string> code: value<string>
label: value<string> label: value<string>
@ -77,6 +77,29 @@ async function fetchRegularLanguages() {
return result.results.bindings return result.results.bindings
} }
async function fetchSignLanguages() {
const query = `
SELECT ?lang ?label ?code
WHERE
{
?lang wdt:P31 wd:Q34228.
OPTIONAL {
?lang wdt:P1813 ?code.
}
?lang rdfs:label ?label.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}`
const url = Wikidata.wds.sparqlQuery(query)
// request the generated URL with your favorite HTTP request library
const result = await Utils.downloadJson<{ results: { bindings: any[] } }>(url, {
"User-Agent": "MapComplete script",
})
return <LanguageSpecResult[]>result.results.bindings
}
/** /**
* Fetches the object as is. Sets a 'code' binding as predifined value * Fetches the object as is. Sets a 'code' binding as predifined value
* @param id * @param id
@ -169,7 +192,20 @@ async function getOfficialLanguagesPerCountryCached(
return officialLanguages return officialLanguages
} }
async function generateSignLanguageOverview(){
const signLanguages = await fetchSignLanguages()
const signPerId = WikidataUtils.extractLanguageData(signLanguages, WikidataUtils.languageRemapping)
const asRecord : Record<string, Record<string, string>> = {}
for (const lng of signPerId.keys()) {
asRecord[lng.toLowerCase()] = Utils.MapToObj(signPerId.get(lng).translations)
}
return asRecord
}
async function main(wipeCache = false) { async function main(wipeCache = false) {
const signLanguages = await generateSignLanguageOverview()
const cacheFile = "./src/assets/generated/languages-wd.json" const cacheFile = "./src/assets/generated/languages-wd.json"
if (wipeCache || !existsSync(cacheFile)) { if (wipeCache || !existsSync(cacheFile)) {
console.log("Refreshing cache") console.log("Refreshing cache")
@ -181,7 +217,8 @@ async function main(wipeCache = false) {
const data = JSON.parse(readFileSync(cacheFile, { encoding: "utf8" })) const data = JSON.parse(readFileSync(cacheFile, { encoding: "utf8" }))
const perId = WikidataUtils.extractLanguageData(data, WikidataUtils.languageRemapping) const perId = WikidataUtils.extractLanguageData(data, WikidataUtils.languageRemapping)
const nativeList = getNativeList(perId) const nativeList = getNativeList(perId)
writeFileSync("./src/assets/language_native.json", JSON.stringify(nativeList, null, " ")) writeFileSync("./src/assets/language_native.json", JSON.stringify({ ...nativeList, ...signLanguages }, null, " "))
const languagesPerCountry = Utils.TransposeMap( const languagesPerCountry = Utils.TransposeMap(
await getOfficialLanguagesPerCountryCached(wipeCache) await getOfficialLanguagesPerCountryCached(wipeCache)
) )

View file

@ -42,7 +42,7 @@
{#if $foundLanguages.length === 0 && on_no_known_languages && !$forceInputMode} {#if $foundLanguages.length === 0 && on_no_known_languages && !$forceInputMode}
<div class="low-interaction flex items-center justify-between rounded p-1"> <div class="low-interaction flex items-center justify-between rounded p-1">
<div> <div class="ml-1">
{on_no_known_languages} {on_no_known_languages}
</div> </div>
<EditButton on:click={(_) => forceInputMode.setData(true)} /> <EditButton on:click={(_) => forceInputMode.setData(true)} />

View file

@ -7,7 +7,7 @@ export class LanguageElement extends SpecialVisualizationSvelte {
needsUrls = [] needsUrls = []
docs: string = docs: string =
"The language element allows to show and pick all known (modern) languages. The key can be set" "The language element allows to show and pick all known (modern) languages (includes sign languages). The key can be set"
args: { args: {
name: string name: string

View file

@ -106,7 +106,7 @@
<Tr t={Translations.t.general.useSearch} /> <Tr t={Translations.t.general.useSearch} />
</label> </label>
<div class="overflow-auto" style="max-height: 25vh"> <div style="max-height: 25vh">
{#each knownLanguagecodes as lng} {#each knownLanguagecodes as lng}
{#if isChecked[lng] && $newlyChecked.indexOf(lng) < 0 && probableLanguages.indexOf(lng) < 0} {#if isChecked[lng] && $newlyChecked.indexOf(lng) < 0 && probableLanguages.indexOf(lng) < 0}
<label class="no-image-background flex items-center gap-1"> <label class="no-image-background flex items-center gap-1">

View file

@ -21,6 +21,7 @@
import { Tag } from "../../../Logic/Tags/Tag" import { Tag } from "../../../Logic/Tags/Tag"
import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction" import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction"
import { And } from "../../../Logic/Tags/And" import { And } from "../../../Logic/Tags/And"
import TagHint from "../TagHint.svelte"
export let question: string export let question: string
export let prefix: string export let prefix: string
@ -67,6 +68,10 @@
} }
dispatch("save") dispatch("save")
} }
const showTags = state.userRelatedState.showTagsB
// For the preview
let asTags = selectedLanguages.mapD(lngs => lngs.map((ln) => new Tag(prefix + ln, "yes")))
</script> </script>
<div class="disable-links interactive border-interactive flex flex-col p-2"> <div class="disable-links interactive border-interactive flex flex-col p-2">
@ -74,7 +79,6 @@
<SpecialTranslation {feature} {layer} {state} t={new Translation({ "*": question })} {tags} /> <SpecialTranslation {feature} {layer} {state} t={new Translation({ "*": question })} {tags} />
</div> </div>
<LanguageOptions {selectedLanguages} countries={$countries} /> <LanguageOptions {selectedLanguages} countries={$countries} />
<div class="flex w-full flex-wrap-reverse justify-end"> <div class="flex w-full flex-wrap-reverse justify-end">
<slot name="cancel-button" /> <slot name="cancel-button" />
<button <button
@ -85,4 +89,9 @@
<Tr t={Translations.t.general.save} /> <Tr t={Translations.t.general.save} />
</button> </button>
</div> </div>
{#if showTags}
<div class="subtle w-fit">
<TagHint tags={$asTags} />
</div>
{/if}
</div> </div>

View file

@ -30,7 +30,11 @@ export default class WikidataUtils {
{ translations: Map<string, string>; directionality?: string[] } { translations: Map<string, string>; directionality?: string[] }
>() >()
for (const element of data) { for (const element of data) {
let id = element.code.value let id = element.code?.value
if(!id){
console.warn("No language code for", JSON.stringify(element),"ignoring")
continue
}
id = remapLanguages[id] ?? id id = remapLanguages[id] ?? id
let labelLang = element.label["xml:lang"] let labelLang = element.label["xml:lang"]
labelLang = remapLanguages[labelLang] ?? labelLang labelLang = remapLanguages[labelLang] ?? labelLang

File diff suppressed because it is too large Load diff