| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  | import { Store, Stores } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import BaseUIElement from "../../UI/BaseUIElement" | 
					
						
							|  |  |  | import { LicenseInfo } from "./LicenseInfo" | 
					
						
							|  |  |  | import { Utils } from "../../Utils" | 
					
						
							| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  | import { Feature, Point } from "geojson" | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | export interface ProvidedImage { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     url: string | 
					
						
							| 
									
										
										
										
											2023-12-07 01:04:43 +01:00
										 |  |  |     url_hd?: string | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     key: string | 
					
						
							| 
									
										
										
										
											2023-12-07 01:04:43 +01:00
										 |  |  |     provider: ImageProvider | 
					
						
							| 
									
										
										
										
											2023-12-02 03:12:34 +01:00
										 |  |  |     id: string | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     date?: Date | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |     status?: string | "ready" | 
					
						
							| 
									
										
										
										
											2024-09-12 01:31:00 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Compass angle of the taken image | 
					
						
							|  |  |  |      * 0 = north, 90° = East | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     rotation?: number | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     lat?: number | 
					
						
							|  |  |  |     lon?: number | 
					
						
							| 
									
										
										
										
											2024-09-30 01:08:07 +02:00
										 |  |  |     host?: string | 
					
						
							| 
									
										
										
										
											2025-04-22 02:53:31 +02:00
										 |  |  |     isSpherical: boolean, | 
					
						
							|  |  |  |     license?: LicenseInfo | 
					
						
							| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface PanoramaView { | 
					
						
							| 
									
										
										
										
											2025-04-15 18:18:44 +02:00
										 |  |  |     url: string | 
					
						
							| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * 0 - 359 | 
					
						
							|  |  |  |      * Degrees in which the picture is taken, with north = 0; going clockwise | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-04-15 18:18:44 +02:00
										 |  |  |     northOffset?: number | 
					
						
							| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  |     pitchOffset?: number | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-30 19:38:36 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The property of "nearbyFeatures" in ImagePreview.svelte. | 
					
						
							|  |  |  |  * These properties declare how they are rendered | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export interface HotspotProperties { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The popup text when hovering | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     name: string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * If true: the panorama view will automatically turn towards this object | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     focus: boolean | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The pitch degrees to display this. | 
					
						
							|  |  |  |      * If "auto": will determine the pitch automatically based on distance | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     pitch: number | "auto" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gotoPanorama: Feature<Point, PanoramaView> | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  | export default abstract class ImageProvider { | 
					
						
							| 
									
										
										
										
											2021-10-18 22:17:41 +02:00
										 |  |  |     public abstract readonly defaultKeyPrefixes: string[] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 12:59:38 +02:00
										 |  |  |     public abstract readonly name: string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     public abstract SourceIcon( | 
					
						
							|  |  |  |         img?: { id: string; url: string; host?: string }, | 
					
						
							|  |  |  |         location?: { lon: number; lat: number } | 
					
						
							|  |  |  |     ): BaseUIElement | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |      * Gets all the relevant URLS for the given tags and for the given prefixes; | 
					
						
							|  |  |  |      * extracts the necessary information | 
					
						
							|  |  |  |      * @param tags | 
					
						
							|  |  |  |      * @param prefixes | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     public async getRelevantUrlsFor( | 
					
						
							|  |  |  |         tags: Record<string, string>, | 
					
						
							|  |  |  |         prefixes: string[] | 
					
						
							|  |  |  |     ): Promise<ProvidedImage[]> { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |         const relevantUrls: ProvidedImage[] = [] | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |         const seenValues = new Set<string>() | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const key in tags) { | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             if ( | 
					
						
							|  |  |  |                 !prefixes.some( | 
					
						
							|  |  |  |                     (prefix) => key === prefix || key.match(new RegExp(prefix + ":[0-9]+")) | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             ) { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const values = Utils.NoEmpty(tags[key]?.split(";")?.map((v) => v.trim()) ?? []) | 
					
						
							|  |  |  |             for (const value of values) { | 
					
						
							|  |  |  |                 if (seenValues.has(value)) { | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |                 seenValues.add(value) | 
					
						
							|  |  |  |                 let images = this.ExtractUrls(key, value) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 if (!Array.isArray(images)) { | 
					
						
							|  |  |  |                     images = await images | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 if (images) { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |                     relevantUrls.push(...images) | 
					
						
							| 
									
										
										
										
											2021-10-07 22:06:47 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-29 23:56:59 +02:00
										 |  |  |         return relevantUrls | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     public getRelevantUrls( | 
					
						
							|  |  |  |         tags: Record<string, string>, | 
					
						
							|  |  |  |         prefixes: string[] | 
					
						
							|  |  |  |     ): Store<ProvidedImage[]> { | 
					
						
							| 
									
										
										
										
											2024-09-28 02:04:14 +02:00
										 |  |  |         return Stores.FromPromise(this.getRelevantUrlsFor(tags, prefixes)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     public abstract ExtractUrls( | 
					
						
							|  |  |  |         key: string, | 
					
						
							|  |  |  |         value: string | 
					
						
							|  |  |  |     ): undefined | ProvidedImage[] | Promise<ProvidedImage[]> | 
					
						
							| 
									
										
										
										
											2021-10-07 22:06:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-21 10:52:51 +02:00
										 |  |  |     public abstract DownloadAttribution(providedImage: { | 
					
						
							|  |  |  |         url: string | 
					
						
							|  |  |  |         id: string | 
					
						
							|  |  |  |     }): Promise<LicenseInfo> | 
					
						
							| 
									
										
										
										
											2023-09-27 22:21:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public abstract apiUrls(): string[] | 
					
						
							| 
									
										
										
										
											2024-11-05 00:18:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-15 18:18:44 +02:00
										 |  |  |     public abstract getPanoramaInfo(image: { | 
					
						
							|  |  |  |         id: string | 
					
						
							|  |  |  |     }): Promise<Feature<Point, PanoramaView>> | undefined | 
					
						
							| 
									
										
										
										
											2025-03-30 03:10:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-07 11:19:15 +01:00
										 |  |  |     public static async offerImageAsDownload(image: ProvidedImage) { | 
					
						
							| 
									
										
										
										
											2024-11-05 00:18:16 +01:00
										 |  |  |         const response = await fetch(image.url_hd ?? image.url) | 
					
						
							|  |  |  |         const blob = await response.blob() | 
					
						
							|  |  |  |         Utils.offerContentsAsDownloadableFile(blob, new URL(image.url).pathname.split("/").at(-1), { | 
					
						
							|  |  |  |             mimetype: "image/jpg", | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |