forked from MapComplete/MapComplete
		
	Refactoring: split NameSuggestionIndex into parts
This commit is contained in:
		
							parent
							
								
									4899065fc4
								
							
						
					
					
						commit
						cf7e005fd1
					
				
					 5 changed files with 103 additions and 139 deletions
				
			
		|  | @ -55,14 +55,18 @@ export interface NSIItem { | |||
|     ext?: string | ||||
| } | ||||
| 
 | ||||
| export class NameSuggestionIndexLight { | ||||
|     public static readonly supportedTypes = ["brand", "flag", "operator", "transit"] as const | ||||
| const supportedTypes = ["brand", "flag", "operator", "transit"] as const | ||||
| export type NsiSupportedType = typeof supportedTypes[number] | ||||
| 
 | ||||
| export default class NameSuggestionIndex { | ||||
|     public static readonly supportedTypes: ReadonlyArray<NsiSupportedType> = ["brand", "flag", "operator", "transit"] as const | ||||
|     protected readonly _serverLocation: string | ||||
|     protected readonly nsiFile: Readonly<NSIFile> | ||||
|     private readonly loco: LocationConflation // Some additional boundaries
 | ||||
|     private static initedLight: NameSuggestionIndexLight = undefined | ||||
|     private static inited: NameSuggestionIndex = undefined | ||||
|     private _supportedTypes: NsiSupportedType[] | ||||
| 
 | ||||
|     protected constructor( | ||||
|     private constructor( | ||||
|         serverLocation: string, | ||||
|         nsiFile: Readonly<NSIFile>, | ||||
|         features: Readonly<FeatureCollection> | ||||
|  | @ -70,7 +74,7 @@ export class NameSuggestionIndexLight { | |||
|         this._serverLocation = serverLocation | ||||
|         this.nsiFile = nsiFile | ||||
|         this.loco = new LocationConflation(features) | ||||
|         NameSuggestionIndexLight.initedLight = this | ||||
|         NameSuggestionIndex.inited = this | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -258,9 +262,9 @@ export class NameSuggestionIndexLight { | |||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     public static async singleton(): Promise<NameSuggestionIndexLight> { | ||||
|         if (NameSuggestionIndexLight.initedLight) { | ||||
|             return NameSuggestionIndexLight.initedLight | ||||
|     public static async singleton(): Promise<NameSuggestionIndex> { | ||||
|         if (NameSuggestionIndex.inited) { | ||||
|             return NameSuggestionIndex.inited | ||||
|         } | ||||
|         const endpoint = Constants.nsiLogosEndpoint ?? "./assets/data/nsi/" | ||||
|         const [nsi, features] = await Promise.all( | ||||
|  | @ -269,70 +273,14 @@ export class NameSuggestionIndexLight { | |||
|                 endpoint + "featureCollection.min.json" | ||||
|             ].map((url) => Utils.downloadJsonCached(url, 1000 * 60 * 60 * 24 * 30)) | ||||
|         ) | ||||
|         return new NameSuggestionIndexLight( | ||||
|         return new NameSuggestionIndex( | ||||
|             endpoint, | ||||
|             <any>nsi, | ||||
|             <any>features | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| export default class NameSuggestionIndex extends NameSuggestionIndexLight { | ||||
|     private readonly nsiWdFile: Readonly< | ||||
|         Record< | ||||
|             string, | ||||
|             { | ||||
|                 logos: { wikidata?: string; facebook?: string } | ||||
|             } | ||||
|         > | ||||
|     > | ||||
| 
 | ||||
| 
 | ||||
|     private _supportedTypes: string[] | ||||
|     private static inited: NameSuggestionIndex = undefined | ||||
| 
 | ||||
|     private constructor( | ||||
|         serverLocation: string, | ||||
|         nsiFile: Readonly<NSIFile>, | ||||
|         nsiWdFile: Readonly< | ||||
|             Record< | ||||
|                 string, | ||||
|                 { | ||||
|                     logos: { wikidata?: string; facebook?: string } | ||||
|                 } | ||||
|             > | ||||
|         >, | ||||
|         features: Readonly<FeatureCollection> | ||||
|     ) { | ||||
|         super(serverLocation, nsiFile, features) | ||||
|         this.nsiWdFile = nsiWdFile | ||||
|         NameSuggestionIndex.inited = this | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public static async getNsiIndex(endPoint ?: string): Promise<NameSuggestionIndex> { | ||||
|         if (NameSuggestionIndex.inited) { | ||||
|             return NameSuggestionIndex.inited | ||||
|         } | ||||
|         endPoint ??= Constants.nsiLogosEndpoint ?? "./assets/data/nsi/" | ||||
|         const [nsi, nsiWd, features] = await Promise.all( | ||||
|             [ | ||||
|                 endPoint + "nsi.min.json", | ||||
|                 endPoint + "wikidata.min.json", | ||||
|                 endPoint + "featureCollection.min.json" | ||||
|             ].map((url) => Utils.downloadJsonCached(url, 1000 * 60 * 60 * 24 * 30)) | ||||
|         ) | ||||
|         return new NameSuggestionIndex( | ||||
|             Constants.nsiLogosEndpoint, | ||||
|             <any>nsi, | ||||
|             <any>nsiWd["wikidata"], | ||||
|             <any>features | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public supportedTypes(): string[] { | ||||
|     public supportedTypes(): NsiSupportedType[] { | ||||
|         if (this._supportedTypes) { | ||||
|             return this._supportedTypes | ||||
|         } | ||||
|  | @ -342,35 +290,13 @@ export default class NameSuggestionIndex extends NameSuggestionIndexLight { | |||
|             if (s.endsWith("s")) { | ||||
|                 s = s.substring(0, s.length - 1) | ||||
|             } | ||||
|             return s | ||||
|             return <NsiSupportedType>s | ||||
|         }) | ||||
|         return this._supportedTypes | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public isSvg(nsiItem: NSIItem, type: string): boolean | undefined { | ||||
|         if (this.nsiWdFile === undefined) { | ||||
|             throw ( | ||||
|                 "nsiWdi file is not loaded, cannot determine if " + nsiItem.id + " has an SVG image" | ||||
|             ) | ||||
|         } | ||||
|         const logos = this.nsiWdFile[nsiItem?.tags?.[type + ":wikidata"]]?.logos | ||||
|         if (!logos) { | ||||
|             return undefined | ||||
|         } | ||||
|         if (logos.facebook) { | ||||
|             return false | ||||
|         } | ||||
|         const url: string = logos.wikidata | ||||
|         if (url.toLowerCase().endsWith(".svg")) { | ||||
|             return true | ||||
|         } | ||||
|         return false | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public supportedTags( | ||||
|         type: "operator" | "brand" | "flag" | "transit" | string | ||||
|         type: NsiSupportedType | ||||
|     ): Record<string, string[]> { | ||||
|         const tags: Record<string, string[]> = {} | ||||
|         const keys = Object.keys(this.nsiFile.nsi) | ||||
|  | @ -389,11 +315,17 @@ export default class NameSuggestionIndex extends NameSuggestionIndexLight { | |||
|         return tags | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public static async getNsiIndex(endPoint ?: string): Promise<NameSuggestionIndex> { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Returns a list of all brands/operators | ||||
|      * @param type | ||||
|      * @param type One of the supported types, e.g. "brand" or "operator" | ||||
|      */ | ||||
|     public allPossible(type: string): NSIItem[] { | ||||
|     public allPossible(type: NsiSupportedType): NSIItem[] { | ||||
|         const options: NSIItem[] = [] | ||||
|         const tags = this.supportedTags(type) | ||||
|         for (const osmKey in tags) { | ||||
|  | @ -412,8 +344,8 @@ export default class NameSuggestionIndex extends NameSuggestionIndexLight { | |||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * @param country: a string containing one or more country codes, separated by ";" | ||||
|      * @param location: center point of the feature, should be [lon, lat] | ||||
|      * @param country a string containing one or more country codes, separated by ";" | ||||
|      * @param location center point of the feature, should be [lon, lat] | ||||
|      */ | ||||
|     public getSuggestionsFor( | ||||
|         type: string, | ||||
|  | @ -436,21 +368,10 @@ export default class NameSuggestionIndex extends NameSuggestionIndexLight { | |||
|             sortByFrequency: boolean | ||||
|         } | ||||
|     ): Promise<Mapping[]> { | ||||
|         const nsi = await NameSuggestionIndexLight.singleton() | ||||
|         const nsi = await NameSuggestionIndex.singleton() | ||||
|         return nsi.generateMappings(key, tags, country, center, options) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Where can we find the URL on the world wide web? | ||||
|      * Probably facebook! Don't use in the website, might expose people | ||||
|      * @param nsiItem | ||||
|      * @param type | ||||
|      */ | ||||
|     private getIconExternalUrl(nsiItem: NSIItem, type: string): string { | ||||
|         const logos = this.nsiWdFile[nsiItem.tags[type + ":wikidata"]]?.logos | ||||
|         return logos?.facebook ?? logos?.wikidata | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private static readonly brandPrefix = ["name", "alt_name", "operator", "brand"] as const | ||||
| 
 | ||||
|  | @ -478,3 +399,61 @@ export default class NameSuggestionIndex extends NameSuggestionIndexLight { | |||
|         return <TagConfigJson>TagUtils.optimzeJson({ and: [...required, { or: brandDetection }] }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class NamgeSuggestionWikidata { | ||||
|     private readonly nsiWdFile: Readonly< | ||||
|         Record< | ||||
|             string, | ||||
|             { | ||||
|                 logos: { wikidata?: string; facebook?: string } | ||||
|             } | ||||
|         > | ||||
|     > | ||||
| 
 | ||||
|     constructor( | ||||
|         nsiWdFile: Readonly< | ||||
|             Record< | ||||
|                 string, | ||||
|                 { | ||||
|                     logos: { wikidata?: string; facebook?: string } | ||||
|                 } | ||||
|             > | ||||
|         > | ||||
|     ) { | ||||
|         this.nsiWdFile = nsiWdFile | ||||
|     } | ||||
| 
 | ||||
|     public isSvg(nsiItem: NSIItem, type: string): boolean | undefined { | ||||
|         if (this.nsiWdFile === undefined) { | ||||
|             throw ( | ||||
|                 "nsiWdi file is not loaded, cannot determine if " + nsiItem.id + " has an SVG image" | ||||
|             ) | ||||
|         } | ||||
|         const logos = this.nsiWdFile[nsiItem?.tags?.[type + ":wikidata"]]?.logos | ||||
|         if (!logos) { | ||||
|             return undefined | ||||
|         } | ||||
|         if (logos.facebook) { | ||||
|             return false | ||||
|         } | ||||
|         const url: string = logos.wikidata | ||||
|         if (url.toLowerCase().endsWith(".svg")) { | ||||
|             return true | ||||
|         } | ||||
|         return false | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Where can we find the URL on the world wide web? | ||||
|      * Probably facebook! Don't use in the website, might expose people | ||||
|      * @param nsiItem | ||||
|      * @param type | ||||
|      */ | ||||
|     private getIconExternalUrl(nsiItem: NSIItem, type: string): string { | ||||
|         const logos = this.nsiWdFile[nsiItem.tags[type + ":wikidata"]]?.logos | ||||
|         return logos?.facebook ?? logos?.wikidata | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue