Chore: ignore 'favourites'-layer when calculating 'usedImages' to display attribution

This commit is contained in:
Pieter Vander Vennet 2024-04-22 14:43:05 +02:00
parent 42fb487d95
commit bfe2398565
4 changed files with 34 additions and 29 deletions

View file

@ -191,7 +191,7 @@ export class ExtractImages extends Conversion<
continue continue
} }
allFoundImages.push({ allFoundImages.push({
context: context + "." + foundElement.path.join("."), context: context.path.join(".") + "." + foundElement.path.join("."),
path: foundElement.leaf, path: foundElement.leaf,
}) })
} }
@ -202,7 +202,7 @@ export class ExtractImages extends Conversion<
for (const foundImage of allFoundImages) { for (const foundImage of allFoundImages) {
if (foundImage.path.startsWith("<") && foundImage.path.endsWith(">")) { if (foundImage.path.startsWith("<") && foundImage.path.endsWith(">")) {
// These is probably html - we ignore // This is probably html
const doc = parse_html(foundImage.path) const doc = parse_html(foundImage.path)
const images = Array.from(doc.getElementsByTagName("img")) const images = Array.from(doc.getElementsByTagName("img"))
const paths = images.map((i) => i.getAttribute("src")) const paths = images.map((i) => i.getAttribute("src"))

View file

@ -11,6 +11,7 @@ import LanguageUtils from "../../Utils/LanguageUtils"
import { RasterLayerProperties } from "../RasterLayerProperties" import { RasterLayerProperties } from "../RasterLayerProperties"
import { ConversionContext } from "./Conversion/ConversionContext" import { ConversionContext } from "./Conversion/ConversionContext"
import { Translatable } from "./Json/Translatable"
/** /**
* Minimal information about a theme * Minimal information about a theme
@ -18,12 +19,12 @@ import { ConversionContext } from "./Conversion/ConversionContext"
export class LayoutInformation { export class LayoutInformation {
id: string id: string
icon: string icon: string
title: any title: Translatable | Translation
shortDescription: any shortDescription: Translatable| Translation
definition?: any definition?: Translatable| Translation
mustHaveLanguage?: boolean mustHaveLanguage?: boolean
hideFromOverview?: boolean hideFromOverview?: boolean
keywords?: any[] keywords?: (Translatable| Translation)[]
} }
export default class LayoutConfig implements LayoutInformation { export default class LayoutConfig implements LayoutInformation {
@ -71,13 +72,14 @@ export default class LayoutConfig implements LayoutInformation {
public readonly osmApiTileSize: number public readonly osmApiTileSize: number
public readonly official: boolean public readonly official: boolean
public readonly usedImages: string[] private usedImages: string[]
public readonly extraLink?: ExtraLinkConfig public readonly extraLink?: ExtraLinkConfig
public readonly definedAtUrl?: string public readonly definedAtUrl?: string
public readonly definitionRaw?: string public readonly definitionRaw?: string
private readonly layersDict: Map<string, LayerConfig> private readonly layersDict: Map<string, LayerConfig>
private readonly source: LayoutConfigJson
constructor( constructor(
json: LayoutConfigJson, json: LayoutConfigJson,
@ -90,6 +92,7 @@ export default class LayoutConfig implements LayoutInformation {
if (json === undefined) { if (json === undefined) {
throw "Cannot construct a layout config, the parameter 'json' is undefined" throw "Cannot construct a layout config, the parameter 'json' is undefined"
} }
this.source = json
this.official = official this.official = official
this.id = json.id this.id = json.id
this.definedAtUrl = options?.definedAtUrl this.definedAtUrl = options?.definedAtUrl
@ -108,11 +111,7 @@ export default class LayoutConfig implements LayoutInformation {
throw `The theme ${json.id} does not have a title defined.` throw `The theme ${json.id} does not have a title defined.`
} }
this.language = json.mustHaveLanguage ?? Object.keys(json.title) this.language = json.mustHaveLanguage ?? Object.keys(json.title)
this.usedImages = Array.from(
new ExtractImages(official, undefined)
.convertStrict(json, ConversionContext.construct([json.id], ["ExtractImages"]))
.map((i) => i.path)
).sort()
{ {
if (typeof json.title === "string") { if (typeof json.title === "string") {
throw `The title of a theme should always be a translation, as it sets the corresponding languages (${context}.title). The themenID is ${ throw `The title of a theme should always be a translation, as it sets the corresponding languages (${context}.title). The themenID is ${
@ -130,17 +129,7 @@ export default class LayoutConfig implements LayoutInformation {
if (json.description === undefined) { if (json.description === undefined) {
throw "Description not defined in " + this.id throw "Description not defined in " + this.id
} }
if (json.widenFactor <= 0) {
throw "Widenfactor too small, shoud be > 0"
}
if (json.widenFactor > 20) {
throw (
"Widenfactor is very big, use a value between 1 and 5 (current value is " +
json.widenFactor +
") at " +
context
)
}
if (json["hideInOverview"]) { if (json["hideInOverview"]) {
throw ( throw (
"The json for " + "The json for " +
@ -172,7 +161,7 @@ export default class LayoutConfig implements LayoutInformation {
this.startZoom = json.startZoom this.startZoom = json.startZoom
this.startLat = json.startLat this.startLat = json.startLat
this.startLon = json.startLon this.startLon = json.startLon
this.widenFactor = json.widenFactor ?? 1.5 this.widenFactor = 1.5
this.defaultBackgroundId = json.defaultBackgroundId this.defaultBackgroundId = json.defaultBackgroundId
this.tileLayerSources = json.tileLayerSources ?? [] this.tileLayerSources = json.tileLayerSources ?? []
@ -259,12 +248,11 @@ export default class LayoutConfig implements LayoutInformation {
untranslated: Map<string, string[]> untranslated: Map<string, string[]>
total: number total: number
} { } {
const layout = this
let total = 0 let total = 0
const untranslated = new Map<string, string[]>() const untranslated = new Map<string, string[]>()
Utils.WalkObject( Utils.WalkObject(
[layout, extraInspection], [this, extraInspection],
(o) => { (o) => {
const translation = <Translation>(<any>o) const translation = <Translation>(<any>o)
if (translation.translations["*"] !== undefined) { if (translation.translations["*"] !== undefined) {
@ -330,4 +318,19 @@ export default class LayoutConfig implements LayoutInformation {
console.log("Fallthrough", this, tags) console.log("Fallthrough", this, tags)
return undefined return undefined
} }
public getUsedImages(){
if(this.usedImages){
return this.usedImages
}
const json = this.source
// The 'favourite'-layer contains pretty much all images as it bundles all layers, so we exclude it
const jsonNoFavourites = {...json, layers: json.layers.filter(l => l["id"] !== "favourite")}
this.usedImages = Array.from(
new ExtractImages(this.official, undefined)
.convertStrict(jsonNoFavourites, ConversionContext.construct([json.id], ["ExtractImages"]))
.map((i) => i.path)
).sort()
return this.usedImages
}
} }

View file

@ -22,7 +22,7 @@ import GeoIndexedStore from "../../Logic/FeatureSource/Actors/GeoIndexedStore"
import { RasterLayerPolygon } from "../../Models/RasterLayers" import { RasterLayerPolygon } from "../../Models/RasterLayers"
/** /**
* The attribution panel in the theme menu. * The attribution panel in the theme menu. Shows the licenses of the artwork and of the map data
*/ */
export default class CopyrightPanel extends Combine { export default class CopyrightPanel extends Combine {
private static LicenseObject = CopyrightPanel.GenerateLicenses() private static LicenseObject = CopyrightPanel.GenerateLicenses()
@ -40,7 +40,9 @@ export default class CopyrightPanel extends Combine {
const t = Translations.t.general.attribution const t = Translations.t.general.attribution
const layoutToUse = state.layout const layoutToUse = state.layout
const iconAttributions: BaseUIElement[] = Utils.Dedup(layoutToUse.usedImages).map(
const iconAttributions: BaseUIElement[] = (layoutToUse.getUsedImages()).map(
CopyrightPanel.IconAttribution CopyrightPanel.IconAttribution
) )

View file

@ -1273,7 +1273,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
public static TransposeMap<K extends string, V extends string>( public static TransposeMap<K extends string, V extends string>(
d: Record<K, V[]> d: Record<K, V[]>
): Record<V, K[]> { ): Record<V, K[]> {
const newD: Record<V, K[]> = <any>{} const newD: Record<V, K[]> = <any> {}
for (const k in d) { for (const k in d) {
const vs = d[k] const vs = d[k]