Fix generateLayerOverview, drop priviliged 'icons.json' from code

This commit is contained in:
Pieter Vander Vennet 2023-02-03 03:57:30 +01:00
parent df3ca4cce3
commit 36aed99843
10 changed files with 267 additions and 167 deletions

View file

@ -1,5 +1,4 @@
import questions from "../assets/tagRenderings/questions.json" import questions from "../assets/tagRenderings/questions.json"
import icons from "../assets/tagRenderings/icons.json"
import { Utils } from "../Utils" import { Utils } from "../Utils"
import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig" import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig"
import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson" import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson"
@ -14,11 +13,9 @@ export default class SharedTagRenderings {
SharedTagRenderings.generatedSharedFields() SharedTagRenderings.generatedSharedFields()
public static SharedTagRenderingJson: Map<string, TagRenderingConfigJson> = public static SharedTagRenderingJson: Map<string, TagRenderingConfigJson> =
SharedTagRenderings.generatedSharedFieldsJsons() SharedTagRenderings.generatedSharedFieldsJsons()
public static SharedIcons: Map<string, TagRenderingConfig> =
SharedTagRenderings.generatedSharedFields(true)
private static generatedSharedFields(iconsOnly = false): Map<string, TagRenderingConfig> { private static generatedSharedFields(): Map<string, TagRenderingConfig> {
const configJsons = SharedTagRenderings.generatedSharedFieldsJsons(iconsOnly) const configJsons = SharedTagRenderings.generatedSharedFieldsJsons()
const d = new Map<string, TagRenderingConfig>() const d = new Map<string, TagRenderingConfig>()
for (const key of Array.from(configJsons.keys())) { for (const key of Array.from(configJsons.keys())) {
try { try {
@ -31,7 +28,7 @@ export default class SharedTagRenderings {
console.error( console.error(
"BUG: could not parse", "BUG: could not parse",
key, key,
" from questions.json or icons.json - this error happened during the build step of the SharedTagRenderings", " from questions.json - this error happened during the build step of the SharedTagRenderings",
e e
) )
} }
@ -40,24 +37,14 @@ export default class SharedTagRenderings {
return d return d
} }
private static generatedSharedFieldsJsons( private static generatedSharedFieldsJsons(): Map<string, TagRenderingConfigJson> {
iconsOnly = false
): Map<string, TagRenderingConfigJson> {
const dict = new Map<string, TagRenderingConfigJson>() const dict = new Map<string, TagRenderingConfigJson>()
if (!iconsOnly) { for (const key in questions) {
for (const key in questions) {
if (key === "id") {
continue
}
dict.set(key, <TagRenderingConfigJson>questions[key])
}
}
for (const key in icons) {
if (key === "id") { if (key === "id") {
continue continue
} }
dict.set(key, <TagRenderingConfigJson>icons[key]) dict.set(key, <TagRenderingConfigJson>questions[key])
} }
dict.forEach((value, key) => { dict.forEach((value, key) => {

View file

@ -194,8 +194,7 @@ export default class DetermineLayout {
let { errors } = new ValidateThemeAndLayers( let { errors } = new ValidateThemeAndLayers(
new DoesImageExist(new Set<string>(), (_) => true), new DoesImageExist(new Set<string>(), (_) => true),
"", "",
false, false
SharedTagRenderings.SharedTagRendering
).convert(json, "validation") ).convert(json, "validation")
if (errors.length > 0) { if (errors.length > 0) {
throw "Detected errors: " + errors.join("\n") throw "Detected errors: " + errors.join("\n")

View file

@ -5,9 +5,12 @@ import metapaths from "../../../assets/layoutconfigmeta.json"
import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json" import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json"
import Translations from "../../../UI/i18n/Translations" import Translations from "../../../UI/i18n/Translations"
export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { export class ExtractImages extends Conversion<
LayoutConfigJson,
{ path: string; context: string }[]
> {
private _isOfficial: boolean private _isOfficial: boolean
private _sharedTagRenderings: Map<string, any> private _sharedTagRenderings: Set<string>
private static readonly layoutMetaPaths = metapaths.filter( private static readonly layoutMetaPaths = metapaths.filter(
(mp) => (mp) =>
@ -16,7 +19,7 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
) )
private static readonly tagRenderingMetaPaths = tagrenderingmetapaths private static readonly tagRenderingMetaPaths = tagrenderingmetapaths
constructor(isOfficial: boolean, sharedTagRenderings: Map<string, any>) { constructor(isOfficial: boolean, sharedTagRenderings: Set<string>) {
super("Extract all images from a layoutConfig using the meta paths.", [], "ExctractImages") super("Extract all images from a layoutConfig using the meta paths.", [], "ExctractImages")
this._isOfficial = isOfficial this._isOfficial = isOfficial
this._sharedTagRenderings = sharedTagRenderings this._sharedTagRenderings = sharedTagRenderings
@ -79,8 +82,8 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
convert( convert(
json: LayoutConfigJson, json: LayoutConfigJson,
context: string context: string
): { result: string[]; errors: string[]; warnings: string[] } { ): { result: { path: string; context: string }[]; errors: string[]; warnings: string[] } {
const allFoundImages: string[] = [] const allFoundImages: { path: string; context: string }[] = []
const errors = [] const errors = []
const warnings = [] const warnings = []
for (const metapath of ExtractImages.layoutMetaPaths) { for (const metapath of ExtractImages.layoutMetaPaths) {
@ -108,7 +111,7 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
continue continue
} }
allFoundImages.push(foundImage) allFoundImages.push({ path: foundImage, context: context + "." + path })
} else { } else {
// This is a tagRendering. // This is a tagRendering.
// Either every rendered value might be an icon // Either every rendered value might be an icon
@ -137,7 +140,10 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
JSON.stringify(img.leaf) JSON.stringify(img.leaf)
) )
} else { } else {
allFoundImages.push(img.leaf) allFoundImages.push({
path: img.leaf,
context: context + "." + path,
})
} }
} }
if (!allRenderedValuesAreImages && isImage) { if (!allRenderedValuesAreImages && isImage) {
@ -146,7 +152,12 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
...Translations.T( ...Translations.T(
img.leaf, img.leaf,
"extract_images from " + img.path.join(".") "extract_images from " + img.path.join(".")
).ExtractImages(false) )
.ExtractImages(false)
.map((path) => ({
path,
context: context + "." + path,
}))
) )
} }
} }
@ -166,15 +177,19 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> {
} }
} }
const splitParts = [] const cleanedImages: { path: string; context: string }[] = []
.concat(
...Utils.NoNull(allFoundImages) for (const foundImage of allFoundImages) {
.map((img) => img["path"] ?? img) // Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"]
.map((img) => img.split(";")) const allPaths = Utils.NoNull(
Utils.NoEmpty(foundImage.path?.split(";")?.map((part) => part.split(":")[0]))
) )
.map((img) => img.split(":")[0]) for (const path of allPaths) {
.filter((img) => img !== "") cleanedImages.push({ path, context: foundImage.context })
return { result: Utils.Dedup(splitParts), errors, warnings } }
}
return { result: cleanedImages, errors, warnings }
} }
} }

View file

@ -7,29 +7,24 @@ import {
FirstOf, FirstOf,
Fuse, Fuse,
On, On,
SetDefault, SetDefault
} from "./Conversion" } from "./Conversion";
import { LayerConfigJson } from "../Json/LayerConfigJson" import { LayerConfigJson } from "../Json/LayerConfigJson";
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson";
import { Utils } from "../../../Utils" 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 tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json" import tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json";
import { AddContextToTranslations } from "./AddContextToTranslations" import { AddContextToTranslations } from "./AddContextToTranslations";
import FilterConfigJson from "../Json/FilterConfigJson" import FilterConfigJson from "../Json/FilterConfigJson";
import predifined_filters from "../../../assets/layers/filters/filters.json" import predifined_filters from "../../../assets/layers/filters/filters.json";
import { TagConfigJson } from "../Json/TagConfigJson";
import PointRenderingConfigJson from "../Json/PointRenderingConfigJson";
import LineRenderingConfigJson from "../Json/LineRenderingConfigJson";
class ExpandFilter extends DesugaringStep<LayerConfigJson> { 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() private static readonly predefinedFilters = ExpandFilter.load_filters()
constructor() { constructor() {
@ -40,6 +35,14 @@ 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
}
convert( convert(
json: LayerConfigJson, json: LayerConfigJson,
context: string context: string
@ -128,6 +131,37 @@ class ExpandTagRendering extends Conversion<
} }
private lookup(name: string): TagRenderingConfigJson[] { private lookup(name: string): TagRenderingConfigJson[] {
const direct = this.directLookup(name)
if (direct === undefined) {
return undefined
}
const result: TagRenderingConfigJson[] = []
for (const tagRenderingConfigJson of direct) {
if (tagRenderingConfigJson["builtin"] !== undefined) {
let nm: string | string[] = tagRenderingConfigJson["builtin"]
let indirect: TagRenderingConfigJson[]
if (typeof nm === "string") {
indirect = this.lookup(nm)
} else {
indirect = [].concat(...nm.map((n) => this.lookup(n)))
}
for (let foundTr of indirect) {
foundTr = Utils.Clone<any>(foundTr)
Utils.Merge(tagRenderingConfigJson["override"] ?? {}, foundTr)
foundTr.id = tagRenderingConfigJson.id ?? foundTr.id
result.push(foundTr)
}
} else {
result.push(tagRenderingConfigJson)
}
}
return result
}
/**
* Looks up a tagRendering based on the name.
*/
private directLookup(name: string): TagRenderingConfigJson[] {
const state = this._state const state = this._state
if (state.tagRenderings.has(name)) { if (state.tagRenderings.has(name)) {
return [state.tagRenderings.get(name)] return [state.tagRenderings.get(name)]
@ -747,6 +781,79 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
} }
} }
class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson | LineRenderingConfigJson> {
private _state: DesugaringContext
private _layer: LayerConfigJson
private _expand: ExpandTagRendering
constructor(state: DesugaringContext, layer: LayerConfigJson) {
super("Expands shorthand properties on iconBadges", ["iconBadges"], "ExpandIconBadges")
this._state = state
this._layer = layer
this._expand = new ExpandTagRendering(state, layer)
}
convert(
json: PointRenderingConfigJson | LineRenderingConfigJson,
context: string
): {
result: PointRenderingConfigJson | LineRenderingConfigJson
errors?: string[]
warnings?: string[]
information?: string[]
} {
if (!json["iconBadges"]) {
return { result: json }
}
const badgesJson = (<PointRenderingConfigJson>json).iconBadges
const iconBadges: { if: TagConfigJson; then: string | TagRenderingConfigJson }[] = []
const errs: string[] = []
const warns: string[] = []
for (let i = 0; i < badgesJson.length; i++) {
const iconBadge: { if: TagConfigJson; then: string | TagRenderingConfigJson } =
badgesJson[i]
const { errors, result, warnings } = this._expand.convert(
iconBadge.then,
context + ".iconBadges[" + i + "]"
)
errs.push(...errors)
warns.push(...warnings)
if (result === undefined) {
iconBadges.push(iconBadge)
continue
}
iconBadges.push(
...result.map((resolved) => ({
if: iconBadge.if,
then: resolved,
}))
)
}
return {
result: { ...json, iconBadges },
errors: errs,
warnings: warns,
}
}
}
class PreparePointRendering extends Fuse<PointRenderingConfigJson | LineRenderingConfigJson> {
constructor(state: DesugaringContext, layer: LayerConfigJson) {
super(
"Prepares point renderings by expanding 'icon' and 'iconBadges'",
new On(
"icon",
new FirstOf(new ExpandTagRendering(state, layer, { applyCondition: false }))
),
new ExpandIconBadges(state, layer)
)
}
}
export class PrepareLayer extends Fuse<LayerConfigJson> { export class PrepareLayer extends Fuse<LayerConfigJson> {
constructor(state: DesugaringContext) { constructor(state: DesugaringContext) {
super( super(
@ -755,19 +862,11 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))), new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))),
new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
new On( new On<(PointRenderingConfigJson | LineRenderingConfigJson)[], LayerConfigJson>(
"mapRendering", "mapRendering",
(layer) => (layer) => new Each(new PreparePointRendering(state, layer))
new Each(
new On(
"icon",
new FirstOf(
new ExpandTagRendering(state, layer, { applyCondition: false })
)
)
)
), ),
new SetDefault("titleIcons", ["defaults"]), new SetDefault("titleIcons", ["icons.defaults"]),
new On("titleIcons", (layer) => new Concat(new ExpandTagRendering(state, layer))), new On("titleIcons", (layer) => new Concat(new ExpandTagRendering(state, layer))),
new ExpandFilter() new ExpandFilter()
) )

View file

@ -59,13 +59,16 @@ class ValidateLanguageCompleteness extends DesugaringStep<any> {
export class DoesImageExist extends DesugaringStep<string> { export class DoesImageExist extends DesugaringStep<string> {
private readonly _knownImagePaths: Set<string> private readonly _knownImagePaths: Set<string>
private readonly _ignore?: Set<string>
private readonly doesPathExist: (path: string) => boolean = undefined private readonly doesPathExist: (path: string) => boolean = undefined
constructor( constructor(
knownImagePaths: Set<string>, knownImagePaths: Set<string>,
checkExistsSync: (path: string) => boolean = undefined checkExistsSync: (path: string) => boolean = undefined,
ignore?: Set<string>
) { ) {
super("Checks if an image exists", [], "DoesImageExist") super("Checks if an image exists", [], "DoesImageExist")
this._ignore = ignore
this._knownImagePaths = knownImagePaths this._knownImagePaths = knownImagePaths
this.doesPathExist = checkExistsSync this.doesPathExist = checkExistsSync
} }
@ -74,6 +77,10 @@ export class DoesImageExist extends DesugaringStep<string> {
image: string, image: string,
context: string context: string
): { result: string; errors?: string[]; warnings?: string[]; information?: string[] } { ): { result: string; errors?: string[]; warnings?: string[]; information?: string[] } {
if (this._ignore?.has(image)) {
return { result: image }
}
const errors = [] const errors = []
const warnings = [] const warnings = []
const information = [] const information = []
@ -123,20 +130,23 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
*/ */
private readonly _path?: string private readonly _path?: string
private readonly _isBuiltin: boolean private readonly _isBuiltin: boolean
private _sharedTagRenderings: Map<string, any> //private readonly _sharedTagRenderings: Map<string, any>
private readonly _validateImage: DesugaringStep<string> private readonly _validateImage: DesugaringStep<string>
private readonly _extractImages: ExtractImages = undefined
constructor( constructor(
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
path: string, path: string,
isBuiltin: boolean, isBuiltin: boolean,
sharedTagRenderings: Map<string, any> sharedTagRenderings?: Set<string>
) { ) {
super("Doesn't change anything, but emits warnings and errors", [], "ValidateTheme") super("Doesn't change anything, but emits warnings and errors", [], "ValidateTheme")
this._validateImage = doesImageExist this._validateImage = doesImageExist
this._path = path this._path = path
this._isBuiltin = isBuiltin this._isBuiltin = isBuiltin
this._sharedTagRenderings = sharedTagRenderings if (sharedTagRenderings) {
this._extractImages = new ExtractImages(this._isBuiltin, sharedTagRenderings)
}
} }
convert( convert(
@ -168,13 +178,10 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
} }
} }
} }
if (this._isBuiltin) { if (this._isBuiltin && this._extractImages !== undefined) {
// Check images: are they local, are the licenses there, is the theme icon square, ... // Check images: are they local, are the licenses there, is the theme icon square, ...
const images = new ExtractImages( const images = this._extractImages.convertStrict(json, "validation")
this._isBuiltin, const remoteImages = images.filter((img) => img.path.indexOf("http") == 0)
this._sharedTagRenderings
).convertStrict(json, "validation")
const remoteImages = images.filter((img) => img.indexOf("http") == 0)
for (const remoteImage of remoteImages) { for (const remoteImage of remoteImages) {
errors.push( errors.push(
"Found a remote image: " + "Found a remote image: " +
@ -186,8 +193,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
} }
for (const image of images) { for (const image of images) {
this._validateImage.convertJoin( this._validateImage.convertJoin(
image, image.path,
context === undefined ? "" : ` in a layer defined in the theme ${context}`, context === undefined ? "" : ` in the theme ${context} at ${image.context}`,
errors, errors,
warnings, warnings,
information information
@ -267,7 +274,7 @@ export class ValidateThemeAndLayers extends Fuse<LayoutConfigJson> {
doesImageExist: DoesImageExist, doesImageExist: DoesImageExist,
path: string, path: string,
isBuiltin: boolean, isBuiltin: boolean,
sharedTagRenderings: Map<string, any> sharedTagRenderings?: Set<string>
) { ) {
super( super(
"Validates a theme and the contained layers", "Validates a theme and the contained layers",
@ -878,53 +885,6 @@ export class DetectDuplicateFilters extends DesugaringStep<{
) )
} }
/**
* Add all filter options into 'perOsmTag'
*/
private addLayerFilters(
layer: LayerConfigJson,
perOsmTag: Map<
string,
{
layer: LayerConfigJson
layout: LayoutConfigJson | undefined
filter: FilterConfigJson
}[]
>,
layout?: LayoutConfigJson | undefined
): void {
if (layer.filter === undefined || layer.filter === null) {
return
}
if (layer.filter["sameAs"] !== undefined) {
return
}
for (const filter of <(string | FilterConfigJson)[]>layer.filter) {
if (typeof filter === "string") {
continue
}
if (filter["#"]?.indexOf("ignore-possible-duplicate") >= 0) {
continue
}
for (const option of filter.options) {
if (option.osmTags === undefined) {
continue
}
const key = JSON.stringify(option.osmTags)
if (!perOsmTag.has(key)) {
perOsmTag.set(key, [])
}
perOsmTag.get(key).push({
layer,
filter,
layout,
})
}
}
}
convert( convert(
json: { layers: LayerConfigJson[]; themes: LayoutConfigJson[] }, json: { layers: LayerConfigJson[]; themes: LayoutConfigJson[] },
context: string context: string
@ -991,4 +951,51 @@ export class DetectDuplicateFilters extends DesugaringStep<{
information, information,
} }
} }
/**
* Add all filter options into 'perOsmTag'
*/
private addLayerFilters(
layer: LayerConfigJson,
perOsmTag: Map<
string,
{
layer: LayerConfigJson
layout: LayoutConfigJson | undefined
filter: FilterConfigJson
}[]
>,
layout?: LayoutConfigJson | undefined
): void {
if (layer.filter === undefined || layer.filter === null) {
return
}
if (layer.filter["sameAs"] !== undefined) {
return
}
for (const filter of <(string | FilterConfigJson)[]>layer.filter) {
if (typeof filter === "string") {
continue
}
if (filter["#"]?.indexOf("ignore-possible-duplicate") >= 0) {
continue
}
for (const option of filter.options) {
if (option.osmTags === undefined) {
continue
}
const key = JSON.stringify(option.osmTags)
if (!perOsmTag.has(key)) {
perOsmTag.set(key, [])
}
perOsmTag.get(key).push({
layer,
filter,
layout,
})
}
}
}
} }

View file

@ -82,10 +82,12 @@ export default class LayoutConfig {
this.credits = json.credits this.credits = json.credits
this.language = json.mustHaveLanguage ?? Object.keys(json.title) this.language = json.mustHaveLanguage ?? Object.keys(json.title)
this.usedImages = Array.from( this.usedImages = Array.from(
new ExtractImages(official, undefined).convertStrict( new ExtractImages(official, undefined)
json, .convertStrict(
"while extracting the images of " + json.id + " " + context ?? "" json,
) "while extracting the images of " + json.id + " " + context ?? ""
)
.map((i) => i.path)
).sort() ).sort()
{ {
if (typeof json.title === "string") { if (typeof json.title === "string") {

View file

@ -1,7 +1,6 @@
import PointRenderingConfigJson from "./Json/PointRenderingConfigJson" import PointRenderingConfigJson from "./Json/PointRenderingConfigJson"
import TagRenderingConfig from "./TagRenderingConfig" import TagRenderingConfig from "./TagRenderingConfig"
import { TagsFilter } from "../../Logic/Tags/TagsFilter" import { TagsFilter } from "../../Logic/Tags/TagsFilter"
import SharedTagRenderings from "../../Customizations/SharedTagRenderings"
import { TagUtils } from "../../Logic/Tags/TagUtils" import { TagUtils } from "../../Logic/Tags/TagUtils"
import { Utils } from "../../Utils" import { Utils } from "../../Utils"
import Svg from "../../Svg" import Svg from "../../Svg"
@ -72,18 +71,9 @@ export default class PointRenderingConfig extends WithContextLoader {
} }
this.cssClasses = this.tr("cssClasses", undefined) this.cssClasses = this.tr("cssClasses", undefined)
this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => { this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => {
let tr: TagRenderingConfig
if (
typeof overlay.then === "string" &&
SharedTagRenderings.SharedIcons.get(overlay.then) !== undefined
) {
tr = SharedTagRenderings.SharedIcons.get(overlay.then)
} else {
tr = new TagRenderingConfig(overlay.then, `iconBadges.${i}`)
}
return { return {
if: TagUtils.Tag(overlay.if), if: TagUtils.Tag(overlay.if),
then: tr, then: new TagRenderingConfig(overlay.then, `iconBadges.${i}`),
} }
}) })

View file

@ -37,7 +37,7 @@
"generate:service-worker": "tsc service-worker.ts && git_hash=$(git rev-parse HEAD) && sed -i'.bkp' \"s/GITHUB-COMMIT/$git_hash/\" service-worker.js && rm service-worker.js.bkp", "generate:service-worker": "tsc service-worker.ts && git_hash=$(git rev-parse HEAD) && sed -i'.bkp' \"s/GITHUB-COMMIT/$git_hash/\" service-worker.js && rm service-worker.js.bkp",
"optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'", "optimize-images": "cd assets/generated/ && find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'",
"generate:stats": "vite-node scripts/GenerateSeries.ts", "generate:stats": "vite-node scripts/GenerateSeries.ts",
"reset:layeroverview": "echo {\\\"layers\\\":[], \\\"themes\\\":[]} > ./assets/generated/known_layers_and_themes.json && echo {\\\"layers\\\": []} > ./assets/generated/known_layers.json && rm -f ./assets/generated/layers/*.json && rm -f ./assets/generated/themes/*.json && npm run generate:layeroverview && vite-node scripts/generateLayerOverview.ts --force", "reset:layeroverview": "echo {\\\"layers\\\":[], \\\"themes\\\":[]} > ./assets/generated/known_layers_and_themes.json && echo {\\\"layers\\\": []} > ./assets/generated/known_layers.json && rm -f ./assets/generated/layers/*.json && rm -f ./assets/generated/themes/*.json && npm run generate:layeroverview && vite-node scripts/generateLayerOverview.ts -- --force",
"generate": "mkdir -p ./assets/generated; npm run generate:licenses; npm run generate:images; npm run generate:charging-stations; npm run generate:translations; npm run reset:layeroverview; npm run generate:service-worker", "generate": "mkdir -p ./assets/generated; npm run generate:licenses; npm run generate:images; npm run generate:charging-stations; npm run generate:translations; npm run reset:layeroverview; npm run generate:service-worker",
"generate:charging-stations": "cd ./assets/layers/charging_station && vite-node csvToJson.ts && cd -", "generate:charging-stations": "cd ./assets/layers/charging_station && vite-node csvToJson.ts && cd -",
"prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh", "prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh",

View file

@ -15,7 +15,6 @@ import {
import { Translation } from "../UI/i18n/Translation" import { Translation } from "../UI/i18n/Translation"
import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson" import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson"
import questions from "../assets/tagRenderings/questions.json" import questions from "../assets/tagRenderings/questions.json"
import icons from "../assets/tagRenderings/icons.json"
import PointRenderingConfigJson from "../Models/ThemeConfig/Json/PointRenderingConfigJson" import PointRenderingConfigJson from "../Models/ThemeConfig/Json/PointRenderingConfigJson"
import { PrepareLayer } from "../Models/ThemeConfig/Conversion/PrepareLayer" import { PrepareLayer } from "../Models/ThemeConfig/Conversion/PrepareLayer"
import { PrepareTheme } from "../Models/ThemeConfig/Conversion/PrepareTheme" import { PrepareTheme } from "../Models/ThemeConfig/Conversion/PrepareTheme"
@ -167,21 +166,6 @@ class LayerOverviewUtils {
) )
dict.set(key, config) dict.set(key, config)
} }
for (const key in icons) {
if (key === "id") {
continue
}
if (typeof icons[key] !== "object") {
continue
}
icons[key].id = key
const config = <TagRenderingConfigJson>icons[key]
validator.convertStrict(
config,
"generate-layer-overview:tagRenderings/icons.json:" + key
)
dict.set(key, config)
}
dict.forEach((value, key) => { dict.forEach((value, key) => {
if (key === "id") { if (key === "id") {
@ -251,7 +235,7 @@ class LayerOverviewUtils {
const sharedLayers = this.buildLayerIndex(doesImageExist, forceReload) const sharedLayers = this.buildLayerIndex(doesImageExist, forceReload)
const recompiledThemes: string[] = [] const recompiledThemes: string[] = []
const sharedThemes = this.buildThemeIndex( const sharedThemes = this.buildThemeIndex(
doesImageExist, licensePaths,
sharedLayers, sharedLayers,
recompiledThemes, recompiledThemes,
forceReload forceReload
@ -381,7 +365,7 @@ class LayerOverviewUtils {
} }
private buildThemeIndex( private buildThemeIndex(
doesImageExist: DoesImageExist, licensePaths: Set<string>,
sharedLayers: Map<string, LayerConfigJson>, sharedLayers: Map<string, LayerConfigJson>,
recompiledThemes: string[], recompiledThemes: string[],
forceReload: boolean forceReload: boolean
@ -396,9 +380,26 @@ class LayerOverviewUtils {
const convertState: DesugaringContext = { const convertState: DesugaringContext = {
sharedLayers, sharedLayers,
tagRenderings: this.getSharedTagRenderings(doesImageExist), tagRenderings: this.getSharedTagRenderings(
new DoesImageExist(licensePaths, existsSync)
),
publicLayers, publicLayers,
} }
const knownTagRenderings = new Set<string>()
convertState.tagRenderings.forEach((_, key) => knownTagRenderings.add(key))
sharedLayers.forEach((layer) => {
for (const tagRendering of layer.tagRenderings ?? []) {
if (tagRendering["id"]) {
knownTagRenderings.add(layer.id + "." + tagRendering["id"])
}
if (tagRendering["labels"]) {
for (const label of tagRendering["labels"]) {
knownTagRenderings.add(layer.id + "." + label)
}
}
}
})
const skippedThemes: string[] = [] const skippedThemes: string[] = []
for (const themeInfo of themeFiles) { for (const themeInfo of themeFiles) {
const themePath = themeInfo.path const themePath = themeInfo.path
@ -433,10 +434,10 @@ class LayerOverviewUtils {
themeFile = new PrepareTheme(convertState).convertStrict(themeFile, themePath) themeFile = new PrepareTheme(convertState).convertStrict(themeFile, themePath)
new ValidateThemeAndLayers( new ValidateThemeAndLayers(
doesImageExist, new DoesImageExist(licensePaths, existsSync, knownTagRenderings),
themePath, themePath,
true, true,
convertState.tagRenderings knownTagRenderings
).convertStrict(themeFile, themePath) ).convertStrict(themeFile, themePath)
if (themeFile.icon.endsWith(".svg")) { if (themeFile.icon.endsWith(".svg")) {

View file

@ -143,7 +143,7 @@ describe("PrepareTheme", () => {
describe("ExtractImages", () => { describe("ExtractImages", () => {
it("should find all images in a themefile", () => { it("should find all images in a themefile", () => {
const images = new Set( const images = new Set(
new ExtractImages(true, new Map<string, any>()).convertStrict(<any>cyclofix, "test") new ExtractImages(true, new Set<string>()).convertStrict(<any>cyclofix, "test")
) )
const expectedValues = [ const expectedValues = [
"./assets/layers/bike_repair_station/repair_station.svg", "./assets/layers/bike_repair_station/repair_station.svg",