forked from MapComplete/MapComplete
		
	Fix generateLayerOverview, drop priviliged 'icons.json' from code
This commit is contained in:
		
							parent
							
								
									df3ca4cce3
								
							
						
					
					
						commit
						36aed99843
					
				
					 10 changed files with 267 additions and 167 deletions
				
			
		|  | @ -1,5 +1,4 @@ | |||
| import questions from "../assets/tagRenderings/questions.json" | ||||
| import icons from "../assets/tagRenderings/icons.json" | ||||
| import { Utils } from "../Utils" | ||||
| import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig" | ||||
| import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson" | ||||
|  | @ -14,11 +13,9 @@ export default class SharedTagRenderings { | |||
|         SharedTagRenderings.generatedSharedFields() | ||||
|     public static SharedTagRenderingJson: Map<string, TagRenderingConfigJson> = | ||||
|         SharedTagRenderings.generatedSharedFieldsJsons() | ||||
|     public static SharedIcons: Map<string, TagRenderingConfig> = | ||||
|         SharedTagRenderings.generatedSharedFields(true) | ||||
| 
 | ||||
|     private static generatedSharedFields(iconsOnly = false): Map<string, TagRenderingConfig> { | ||||
|         const configJsons = SharedTagRenderings.generatedSharedFieldsJsons(iconsOnly) | ||||
|     private static generatedSharedFields(): Map<string, TagRenderingConfig> { | ||||
|         const configJsons = SharedTagRenderings.generatedSharedFieldsJsons() | ||||
|         const d = new Map<string, TagRenderingConfig>() | ||||
|         for (const key of Array.from(configJsons.keys())) { | ||||
|             try { | ||||
|  | @ -31,7 +28,7 @@ export default class SharedTagRenderings { | |||
|                     console.error( | ||||
|                         "BUG: could not parse", | ||||
|                         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 | ||||
|                     ) | ||||
|                 } | ||||
|  | @ -40,24 +37,14 @@ export default class SharedTagRenderings { | |||
|         return d | ||||
|     } | ||||
| 
 | ||||
|     private static generatedSharedFieldsJsons( | ||||
|         iconsOnly = false | ||||
|     ): Map<string, TagRenderingConfigJson> { | ||||
|     private static generatedSharedFieldsJsons(): Map<string, TagRenderingConfigJson> { | ||||
|         const dict = new Map<string, TagRenderingConfigJson>() | ||||
| 
 | ||||
|         if (!iconsOnly) { | ||||
|             for (const key in questions) { | ||||
|                 if (key === "id") { | ||||
|                     continue | ||||
|                 } | ||||
|                 dict.set(key, <TagRenderingConfigJson>questions[key]) | ||||
|             } | ||||
|         } | ||||
|         for (const key in icons) { | ||||
|         for (const key in questions) { | ||||
|             if (key === "id") { | ||||
|                 continue | ||||
|             } | ||||
|             dict.set(key, <TagRenderingConfigJson>icons[key]) | ||||
|             dict.set(key, <TagRenderingConfigJson>questions[key]) | ||||
|         } | ||||
| 
 | ||||
|         dict.forEach((value, key) => { | ||||
|  |  | |||
|  | @ -194,8 +194,7 @@ export default class DetermineLayout { | |||
|             let { errors } = new ValidateThemeAndLayers( | ||||
|                 new DoesImageExist(new Set<string>(), (_) => true), | ||||
|                 "", | ||||
|                 false, | ||||
|                 SharedTagRenderings.SharedTagRendering | ||||
|                 false | ||||
|             ).convert(json, "validation") | ||||
|             if (errors.length > 0) { | ||||
|                 throw "Detected errors: " + errors.join("\n") | ||||
|  |  | |||
|  | @ -5,9 +5,12 @@ import metapaths from "../../../assets/layoutconfigmeta.json" | |||
| import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json" | ||||
| 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 _sharedTagRenderings: Map<string, any> | ||||
|     private _sharedTagRenderings: Set<string> | ||||
| 
 | ||||
|     private static readonly layoutMetaPaths = metapaths.filter( | ||||
|         (mp) => | ||||
|  | @ -16,7 +19,7 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | |||
|     ) | ||||
|     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") | ||||
|         this._isOfficial = isOfficial | ||||
|         this._sharedTagRenderings = sharedTagRenderings | ||||
|  | @ -79,8 +82,8 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | |||
|     convert( | ||||
|         json: LayoutConfigJson, | ||||
|         context: string | ||||
|     ): { result: string[]; errors: string[]; warnings: string[] } { | ||||
|         const allFoundImages: string[] = [] | ||||
|     ): { result: { path: string; context: string }[]; errors: string[]; warnings: string[] } { | ||||
|         const allFoundImages: { path: string; context: string }[] = [] | ||||
|         const errors = [] | ||||
|         const warnings = [] | ||||
|         for (const metapath of ExtractImages.layoutMetaPaths) { | ||||
|  | @ -108,7 +111,7 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | |||
|                             continue | ||||
|                         } | ||||
| 
 | ||||
|                         allFoundImages.push(foundImage) | ||||
|                         allFoundImages.push({ path: foundImage, context: context + "." + path }) | ||||
|                     } else { | ||||
|                         // This is a tagRendering.
 | ||||
|                         // Either every rendered value might be an icon
 | ||||
|  | @ -137,7 +140,10 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | |||
|                                                 JSON.stringify(img.leaf) | ||||
|                                         ) | ||||
|                                     } else { | ||||
|                                         allFoundImages.push(img.leaf) | ||||
|                                         allFoundImages.push({ | ||||
|                                             path: img.leaf, | ||||
|                                             context: context + "." + path, | ||||
|                                         }) | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if (!allRenderedValuesAreImages && isImage) { | ||||
|  | @ -146,7 +152,12 @@ export class ExtractImages extends Conversion<LayoutConfigJson, string[]> { | |||
|                                         ...Translations.T( | ||||
|                                             img.leaf, | ||||
|                                             "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 = [] | ||||
|             .concat( | ||||
|                 ...Utils.NoNull(allFoundImages) | ||||
|                     .map((img) => img["path"] ?? img) | ||||
|                     .map((img) => img.split(";")) | ||||
|         const cleanedImages: { path: string; context: string }[] = [] | ||||
| 
 | ||||
|         for (const foundImage of allFoundImages) { | ||||
|             // Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"]
 | ||||
|             const allPaths = Utils.NoNull( | ||||
|                 Utils.NoEmpty(foundImage.path?.split(";")?.map((part) => part.split(":")[0])) | ||||
|             ) | ||||
|             .map((img) => img.split(":")[0]) | ||||
|             .filter((img) => img !== "") | ||||
|         return { result: Utils.Dedup(splitParts), errors, warnings } | ||||
|             for (const path of allPaths) { | ||||
|                 cleanedImages.push({ path, context: foundImage.context }) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return { result: cleanedImages, errors, warnings } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,29 +7,24 @@ import { | |||
|     FirstOf, | ||||
|     Fuse, | ||||
|     On, | ||||
|     SetDefault, | ||||
| } from "./Conversion" | ||||
| import { LayerConfigJson } from "../Json/LayerConfigJson" | ||||
| import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" | ||||
| import { Utils } from "../../../Utils" | ||||
| import RewritableConfigJson from "../Json/RewritableConfigJson" | ||||
| import SpecialVisualizations from "../../../UI/SpecialVisualizations" | ||||
| import Translations from "../../../UI/i18n/Translations" | ||||
| import { Translation } from "../../../UI/i18n/Translation" | ||||
| import tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json" | ||||
| import { AddContextToTranslations } from "./AddContextToTranslations" | ||||
| import FilterConfigJson from "../Json/FilterConfigJson" | ||||
| import predifined_filters from "../../../assets/layers/filters/filters.json" | ||||
|     SetDefault | ||||
| } from "./Conversion"; | ||||
| import { LayerConfigJson } from "../Json/LayerConfigJson"; | ||||
| import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"; | ||||
| import { Utils } from "../../../Utils"; | ||||
| import RewritableConfigJson from "../Json/RewritableConfigJson"; | ||||
| import SpecialVisualizations from "../../../UI/SpecialVisualizations"; | ||||
| import Translations from "../../../UI/i18n/Translations"; | ||||
| import { Translation } from "../../../UI/i18n/Translation"; | ||||
| import tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json"; | ||||
| import { AddContextToTranslations } from "./AddContextToTranslations"; | ||||
| import FilterConfigJson from "../Json/FilterConfigJson"; | ||||
| 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> { | ||||
|     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() | ||||
| 
 | ||||
|     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( | ||||
|         json: LayerConfigJson, | ||||
|         context: string | ||||
|  | @ -128,6 +131,37 @@ class ExpandTagRendering extends Conversion< | |||
|     } | ||||
| 
 | ||||
|     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 | ||||
|         if (state.tagRenderings.has(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> { | ||||
|     constructor(state: DesugaringContext) { | ||||
|         super( | ||||
|  | @ -755,19 +862,11 @@ export class PrepareLayer extends Fuse<LayerConfigJson> { | |||
|             new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), | ||||
|             new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))), | ||||
|             new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), | ||||
|             new On( | ||||
|             new On<(PointRenderingConfigJson | LineRenderingConfigJson)[], LayerConfigJson>( | ||||
|                 "mapRendering", | ||||
|                 (layer) => | ||||
|                     new Each( | ||||
|                         new On( | ||||
|                             "icon", | ||||
|                             new FirstOf( | ||||
|                                 new ExpandTagRendering(state, layer, { applyCondition: false }) | ||||
|                             ) | ||||
|                         ) | ||||
|                     ) | ||||
|                 (layer) => new Each(new PreparePointRendering(state, layer)) | ||||
|             ), | ||||
|             new SetDefault("titleIcons", ["defaults"]), | ||||
|             new SetDefault("titleIcons", ["icons.defaults"]), | ||||
|             new On("titleIcons", (layer) => new Concat(new ExpandTagRendering(state, layer))), | ||||
|             new ExpandFilter() | ||||
|         ) | ||||
|  |  | |||
|  | @ -59,13 +59,16 @@ class ValidateLanguageCompleteness extends DesugaringStep<any> { | |||
| 
 | ||||
| export class DoesImageExist extends DesugaringStep<string> { | ||||
|     private readonly _knownImagePaths: Set<string> | ||||
|     private readonly _ignore?: Set<string> | ||||
|     private readonly doesPathExist: (path: string) => boolean = undefined | ||||
| 
 | ||||
|     constructor( | ||||
|         knownImagePaths: Set<string>, | ||||
|         checkExistsSync: (path: string) => boolean = undefined | ||||
|         checkExistsSync: (path: string) => boolean = undefined, | ||||
|         ignore?: Set<string> | ||||
|     ) { | ||||
|         super("Checks if an image exists", [], "DoesImageExist") | ||||
|         this._ignore = ignore | ||||
|         this._knownImagePaths = knownImagePaths | ||||
|         this.doesPathExist = checkExistsSync | ||||
|     } | ||||
|  | @ -74,6 +77,10 @@ export class DoesImageExist extends DesugaringStep<string> { | |||
|         image: string, | ||||
|         context: string | ||||
|     ): { result: string; errors?: string[]; warnings?: string[]; information?: string[] } { | ||||
|         if (this._ignore?.has(image)) { | ||||
|             return { result: image } | ||||
|         } | ||||
| 
 | ||||
|         const errors = [] | ||||
|         const warnings = [] | ||||
|         const information = [] | ||||
|  | @ -123,20 +130,23 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|      */ | ||||
|     private readonly _path?: string | ||||
|     private readonly _isBuiltin: boolean | ||||
|     private _sharedTagRenderings: Map<string, any> | ||||
|     //private readonly _sharedTagRenderings: Map<string, any>
 | ||||
|     private readonly _validateImage: DesugaringStep<string> | ||||
|     private readonly _extractImages: ExtractImages = undefined | ||||
| 
 | ||||
|     constructor( | ||||
|         doesImageExist: DoesImageExist, | ||||
|         path: string, | ||||
|         isBuiltin: boolean, | ||||
|         sharedTagRenderings: Map<string, any> | ||||
|         sharedTagRenderings?: Set<string> | ||||
|     ) { | ||||
|         super("Doesn't change anything, but emits warnings and errors", [], "ValidateTheme") | ||||
|         this._validateImage = doesImageExist | ||||
|         this._path = path | ||||
|         this._isBuiltin = isBuiltin | ||||
|         this._sharedTagRenderings = sharedTagRenderings | ||||
|         if (sharedTagRenderings) { | ||||
|             this._extractImages = new ExtractImages(this._isBuiltin, sharedTagRenderings) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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, ...
 | ||||
|             const images = new ExtractImages( | ||||
|                 this._isBuiltin, | ||||
|                 this._sharedTagRenderings | ||||
|             ).convertStrict(json, "validation") | ||||
|             const remoteImages = images.filter((img) => img.indexOf("http") == 0) | ||||
|             const images = this._extractImages.convertStrict(json, "validation") | ||||
|             const remoteImages = images.filter((img) => img.path.indexOf("http") == 0) | ||||
|             for (const remoteImage of remoteImages) { | ||||
|                 errors.push( | ||||
|                     "Found a remote image: " + | ||||
|  | @ -186,8 +193,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> { | |||
|             } | ||||
|             for (const image of images) { | ||||
|                 this._validateImage.convertJoin( | ||||
|                     image, | ||||
|                     context === undefined ? "" : ` in a layer defined in the theme ${context}`, | ||||
|                     image.path, | ||||
|                     context === undefined ? "" : ` in the theme ${context} at ${image.context}`, | ||||
|                     errors, | ||||
|                     warnings, | ||||
|                     information | ||||
|  | @ -267,7 +274,7 @@ export class ValidateThemeAndLayers extends Fuse<LayoutConfigJson> { | |||
|         doesImageExist: DoesImageExist, | ||||
|         path: string, | ||||
|         isBuiltin: boolean, | ||||
|         sharedTagRenderings: Map<string, any> | ||||
|         sharedTagRenderings?: Set<string> | ||||
|     ) { | ||||
|         super( | ||||
|             "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( | ||||
|         json: { layers: LayerConfigJson[]; themes: LayoutConfigJson[] }, | ||||
|         context: string | ||||
|  | @ -991,4 +951,51 @@ export class DetectDuplicateFilters extends DesugaringStep<{ | |||
|             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, | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -82,10 +82,12 @@ export default class LayoutConfig { | |||
|         this.credits = json.credits | ||||
|         this.language = json.mustHaveLanguage ?? Object.keys(json.title) | ||||
|         this.usedImages = Array.from( | ||||
|             new ExtractImages(official, undefined).convertStrict( | ||||
|                 json, | ||||
|                 "while extracting the images of " + json.id + " " + context ?? "" | ||||
|             ) | ||||
|             new ExtractImages(official, undefined) | ||||
|                 .convertStrict( | ||||
|                     json, | ||||
|                     "while extracting the images of " + json.id + " " + context ?? "" | ||||
|                 ) | ||||
|                 .map((i) => i.path) | ||||
|         ).sort() | ||||
|         { | ||||
|             if (typeof json.title === "string") { | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import PointRenderingConfigJson from "./Json/PointRenderingConfigJson" | ||||
| import TagRenderingConfig from "./TagRenderingConfig" | ||||
| import { TagsFilter } from "../../Logic/Tags/TagsFilter" | ||||
| import SharedTagRenderings from "../../Customizations/SharedTagRenderings" | ||||
| import { TagUtils } from "../../Logic/Tags/TagUtils" | ||||
| import { Utils } from "../../Utils" | ||||
| import Svg from "../../Svg" | ||||
|  | @ -72,18 +71,9 @@ export default class PointRenderingConfig extends WithContextLoader { | |||
|         } | ||||
|         this.cssClasses = this.tr("cssClasses", undefined) | ||||
|         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 { | ||||
|                 if: TagUtils.Tag(overlay.if), | ||||
|                 then: tr, | ||||
|                 then: new TagRenderingConfig(overlay.then, `iconBadges.${i}`), | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|  |  | |||
|  | @ -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", | ||||
|     "optimize-images": "cd assets/generated/ &&  find -name '*.png' -exec optipng '{}' \\; && echo 'PNGs are optimized'", | ||||
|     "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:charging-stations": "cd ./assets/layers/charging_station && vite-node csvToJson.ts && cd -", | ||||
|     "prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh", | ||||
|  |  | |||
|  | @ -15,7 +15,6 @@ import { | |||
| import { Translation } from "../UI/i18n/Translation" | ||||
| import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson" | ||||
| import questions from "../assets/tagRenderings/questions.json" | ||||
| import icons from "../assets/tagRenderings/icons.json" | ||||
| import PointRenderingConfigJson from "../Models/ThemeConfig/Json/PointRenderingConfigJson" | ||||
| import { PrepareLayer } from "../Models/ThemeConfig/Conversion/PrepareLayer" | ||||
| import { PrepareTheme } from "../Models/ThemeConfig/Conversion/PrepareTheme" | ||||
|  | @ -167,21 +166,6 @@ class LayerOverviewUtils { | |||
|             ) | ||||
|             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) => { | ||||
|             if (key === "id") { | ||||
|  | @ -251,7 +235,7 @@ class LayerOverviewUtils { | |||
|         const sharedLayers = this.buildLayerIndex(doesImageExist, forceReload) | ||||
|         const recompiledThemes: string[] = [] | ||||
|         const sharedThemes = this.buildThemeIndex( | ||||
|             doesImageExist, | ||||
|             licensePaths, | ||||
|             sharedLayers, | ||||
|             recompiledThemes, | ||||
|             forceReload | ||||
|  | @ -381,7 +365,7 @@ class LayerOverviewUtils { | |||
|     } | ||||
| 
 | ||||
|     private buildThemeIndex( | ||||
|         doesImageExist: DoesImageExist, | ||||
|         licensePaths: Set<string>, | ||||
|         sharedLayers: Map<string, LayerConfigJson>, | ||||
|         recompiledThemes: string[], | ||||
|         forceReload: boolean | ||||
|  | @ -396,9 +380,26 @@ class LayerOverviewUtils { | |||
| 
 | ||||
|         const convertState: DesugaringContext = { | ||||
|             sharedLayers, | ||||
|             tagRenderings: this.getSharedTagRenderings(doesImageExist), | ||||
|             tagRenderings: this.getSharedTagRenderings( | ||||
|                 new DoesImageExist(licensePaths, existsSync) | ||||
|             ), | ||||
|             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[] = [] | ||||
|         for (const themeInfo of themeFiles) { | ||||
|             const themePath = themeInfo.path | ||||
|  | @ -433,10 +434,10 @@ class LayerOverviewUtils { | |||
|                 themeFile = new PrepareTheme(convertState).convertStrict(themeFile, themePath) | ||||
| 
 | ||||
|                 new ValidateThemeAndLayers( | ||||
|                     doesImageExist, | ||||
|                     new DoesImageExist(licensePaths, existsSync, knownTagRenderings), | ||||
|                     themePath, | ||||
|                     true, | ||||
|                     convertState.tagRenderings | ||||
|                     knownTagRenderings | ||||
|                 ).convertStrict(themeFile, themePath) | ||||
| 
 | ||||
|                 if (themeFile.icon.endsWith(".svg")) { | ||||
|  |  | |||
|  | @ -143,7 +143,7 @@ describe("PrepareTheme", () => { | |||
| describe("ExtractImages", () => { | ||||
|     it("should find all images in a themefile", () => { | ||||
|         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 = [ | ||||
|             "./assets/layers/bike_repair_station/repair_station.svg", | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue