forked from MapComplete/MapComplete
86 lines
3 KiB
TypeScript
86 lines
3 KiB
TypeScript
import ImageProvider, { PanoramaView, ProvidedImage } from "./ImageProvider"
|
|
import BaseUIElement from "../../UI/BaseUIElement"
|
|
import { WikimediaImageProvider } from "./WikimediaImageProvider"
|
|
import Wikidata from "../Web/Wikidata"
|
|
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
|
import * as Wikidata_icon from "../../assets/svg/Wikidata.svelte"
|
|
import { Utils } from "../../Utils"
|
|
import { Feature, Point } from "geojson"
|
|
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
|
|
|
export class WikidataImageProvider extends ImageProvider {
|
|
public static readonly singleton = new WikidataImageProvider()
|
|
public readonly defaultKeyPrefixes = ["wikidata"]
|
|
public readonly name = "Wikidata"
|
|
private static readonly keyBlacklist: ReadonlySet<string> = new Set([
|
|
"mapillary",
|
|
...Utils.Times((i) => "mapillary:" + i, 10),
|
|
])
|
|
|
|
private constructor() {
|
|
super()
|
|
}
|
|
|
|
public apiUrls(): ServerSourceInfo[] {
|
|
return Wikidata.neededUrls
|
|
}
|
|
|
|
public SourceIcon(): BaseUIElement {
|
|
return new SvelteUIElement(Wikidata_icon)
|
|
}
|
|
|
|
public async ExtractUrls(key: string, value: string): Promise<ProvidedImage[]> {
|
|
if (WikidataImageProvider.keyBlacklist.has(key)) {
|
|
return undefined
|
|
}
|
|
const entity = await Wikidata.LoadWikidataEntryAsync(value)
|
|
if (entity === undefined) {
|
|
return undefined
|
|
}
|
|
|
|
const allImages: Promise<ProvidedImage[]>[] = []
|
|
// P18 is the claim 'depicted in this image'
|
|
for (const img of Array.from(entity.claims.get("P18") ?? [])) {
|
|
const promises = WikimediaImageProvider.singleton.ExtractUrls(undefined, img)
|
|
allImages.push(promises)
|
|
}
|
|
// P373 is 'commons category'
|
|
for (let cat of Array.from(entity.claims.get("P373") ?? [])) {
|
|
if (!cat.startsWith("Category:")) {
|
|
cat = "Category:" + cat
|
|
}
|
|
const promises = WikimediaImageProvider.singleton.ExtractUrls(undefined, cat)
|
|
allImages.push(promises)
|
|
}
|
|
|
|
const commons = entity.commons
|
|
if (
|
|
commons !== undefined &&
|
|
(commons.startsWith("Category:") || commons.startsWith("File:"))
|
|
) {
|
|
const promises = WikimediaImageProvider.singleton.ExtractUrls(undefined, commons)
|
|
allImages.push(promises)
|
|
}
|
|
const resolved = await Promise.all(Utils.NoNull(allImages))
|
|
const flattened = resolved.flatMap((x) => x)
|
|
if (flattened.length === 1) {
|
|
flattened[0].originalAttribute = { key, value }
|
|
}
|
|
return flattened
|
|
}
|
|
|
|
public DownloadAttribution(): Promise<undefined> {
|
|
throw new Error("Method not implemented; shouldn't be needed!")
|
|
}
|
|
|
|
public getPanoramaInfo(image: { id: string }): Promise<Feature<Point, PanoramaView>> {
|
|
return undefined
|
|
}
|
|
|
|
visitUrl(
|
|
image: Partial<ProvidedImage>,
|
|
location?: { lon: number; lat: number }
|
|
): string | undefined {
|
|
return undefined
|
|
}
|
|
}
|