forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			115 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import ImageProvider, { ProvidedImage } from "./ImageProvider"
 | |
| import BaseUIElement from "../../UI/BaseUIElement"
 | |
| import Svg from "../../Svg"
 | |
| import { Utils } from "../../Utils"
 | |
| import { LicenseInfo } from "./LicenseInfo"
 | |
| import Constants from "../../Models/Constants"
 | |
| 
 | |
| export class Mapillary extends ImageProvider {
 | |
|     public static readonly singleton = new Mapillary()
 | |
|     private static readonly valuePrefix = "https://a.mapillary.com"
 | |
|     public static readonly valuePrefixes = [
 | |
|         Mapillary.valuePrefix,
 | |
|         "http://mapillary.com",
 | |
|         "https://mapillary.com",
 | |
|         "http://www.mapillary.com",
 | |
|         "https://www.mapillary.com",
 | |
|     ]
 | |
|     defaultKeyPrefixes = ["mapillary", "image"]
 | |
| 
 | |
|     /**
 | |
|      * Indicates that this is the same URL
 | |
|      * Ignores 'stp' parameter
 | |
|      *
 | |
|      * const a = "https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8xm5SGLt20ETziNqzhhBd8b8S5GHLiIu8N6BbyqHFohFAQoaJJPG8i5yQiSwjYmEqXSfVeoCmpiyBJICEkQK98JOB21kkJoBS8VdhYa-Ty93lBnznQyesJBtKcb32foGut2Hgt10hEMWJbE3dDgA?stp=s1024x768&ccb=10-5&oh=00_AT-ZGTXHzihoaQYBILmEiAEKR64z_IWiTlcAYq_D7Ka0-Q&oe=6278C456&_nc_sid=122ab1"
 | |
|      * const b = "https://scontent-bru2-1.xx.fbcdn.net/m1/v/t6/An8xm5SGLt20ETziNqzhhBd8b8S5GHLiIu8N6BbyqHFohFAQoaJJPG8i5yQiSwjYmEqXSfVeoCmpiyBJICEkQK98JOB21kkJoBS8VdhYa-Ty93lBnznQyesJBtKcb32foGut2Hgt10hEMWJbE3dDgA?stp=s256x192&ccb=10-5&oh=00_AT9BZ1Rpc9zbY_uNu92A_4gj1joiy1b6VtgtLIu_7wh9Bg&oe=6278C456&_nc_sid=122ab1"
 | |
|      * Mapillary.sameUrl(a, b) => true
 | |
|      */
 | |
|     static sameUrl(a: string, b: string): boolean {
 | |
|         if (a === b) {
 | |
|             return true
 | |
|         }
 | |
|         try {
 | |
|             const aUrl = new URL(a)
 | |
|             const bUrl = new URL(b)
 | |
|             if (aUrl.host !== bUrl.host || aUrl.pathname !== bUrl.pathname) {
 | |
|                 return false
 | |
|             }
 | |
|             let allSame = true
 | |
|             aUrl.searchParams.forEach((value, key) => {
 | |
|                 if (key === "stp") {
 | |
|                     // This is the key indicating the image size on mapillary; we ignore it
 | |
|                     return
 | |
|                 }
 | |
|                 if (value !== bUrl.searchParams.get(key)) {
 | |
|                     allSame = false
 | |
|                     return
 | |
|                 }
 | |
|             })
 | |
|             return allSame
 | |
|         } catch (e) {
 | |
|             console.debug("Could not compare ", a, "and", b, "due to", e)
 | |
|         }
 | |
|         return false
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Returns the correct key for API v4.0
 | |
|      */
 | |
|     private static ExtractKeyFromURL(value: string): number {
 | |
|         let key: string
 | |
| 
 | |
|         const newApiFormat = value.match(/https?:\/\/www.mapillary.com\/app\/\?pKey=([0-9]*)/)
 | |
|         if (newApiFormat !== null) {
 | |
|             key = newApiFormat[1]
 | |
|         } else if (value.startsWith(Mapillary.valuePrefix)) {
 | |
|             key = value.substring(0, value.lastIndexOf("?")).substring(value.lastIndexOf("/") + 1)
 | |
|         } else if (value.match("[0-9]*")) {
 | |
|             key = value
 | |
|         }
 | |
| 
 | |
|         const keyAsNumber = Number(key)
 | |
|         if (!isNaN(keyAsNumber)) {
 | |
|             return keyAsNumber
 | |
|         }
 | |
| 
 | |
|         return undefined
 | |
|     }
 | |
| 
 | |
|     SourceIcon(backlinkSource?: string): BaseUIElement {
 | |
|         return Svg.mapillary_svg()
 | |
|     }
 | |
| 
 | |
|     async ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]> {
 | |
|         return [this.PrepareUrlAsync(key, value)]
 | |
|     }
 | |
| 
 | |
|     public async DownloadAttribution(url: string): Promise<LicenseInfo> {
 | |
|         const license = new LicenseInfo()
 | |
|         license.artist = "Contributor name unavailable"
 | |
|         license.license = "CC BY-SA 4.0"
 | |
|         // license.license = "Creative Commons Attribution-ShareAlike 4.0 International License";
 | |
|         license.attributionRequired = true
 | |
|         return license
 | |
|     }
 | |
| 
 | |
|     private async PrepareUrlAsync(key: string, value: string): Promise<ProvidedImage> {
 | |
|         const mapillaryId = Mapillary.ExtractKeyFromURL(value)
 | |
|         if (mapillaryId === undefined) {
 | |
|             return undefined
 | |
|         }
 | |
| 
 | |
|         const metadataUrl =
 | |
|             "https://graph.mapillary.com/" +
 | |
|             mapillaryId +
 | |
|             "?fields=thumb_1024_url&&access_token=" +
 | |
|             Constants.mapillary_client_token_v4
 | |
|         const response = await Utils.downloadJsonCached(metadataUrl, 60 * 60)
 | |
|         const url = <string>response["thumb_1024_url"]
 | |
|         return {
 | |
|             url: url,
 | |
|             provider: this,
 | |
|             key: key,
 | |
|         }
 | |
|     }
 | |
| }
 |