2025-01-27 04:50:44 +01:00
import { SpecialVisualizationState , SpecialVisualizationSvelte } from "../SpecialVisualization"
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
import SvelteUIElement from "../Base/SvelteUIElement"
import ImageCarousel from "../Image/ImageCarousel.svelte"
import { Imgur } from "../../Logic/ImageProviders/Imgur"
import UploadImage from "../Image/UploadImage.svelte"
import { CombinedFetcher } from "../../Logic/Web/NearbyImagesSearch"
import { UIEventSource } from "../../Logic/UIEventSource"
import { Feature } from "geojson"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { GeoOperations } from "../../Logic/GeoOperations"
import NearbyImages from "../Image/NearbyImages.svelte"
import NearbyImagesCollapsed from "../Image/NearbyImagesCollapsed.svelte"
class NearbyImageVis implements SpecialVisualizationSvelte {
// Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
args : { name : string ; defaultValue? : string ; doc : string ; required? : boolean } [ ] = [
{
name : "mode" ,
defaultValue : "closed" ,
2025-02-10 02:04:58 +01:00
doc : "Either `open` or `closed`. If `open`, then the image carousel will always be shown" ,
2025-01-27 04:50:44 +01:00
} ,
{
name : "readonly" ,
required : false ,
2025-02-10 02:04:58 +01:00
doc : "If 'readonly' or 'yes', will not show the 'link'-button" ,
} ,
2025-01-27 04:50:44 +01:00
]
group : "images"
docs =
"A component showing nearby images loaded from various online services such as Mapillary. In edit mode and when used on a feature, the user can select an image to add to the feature"
funcName = "nearby_images"
needsUrls = CombinedFetcher . apiUrls
constr (
state : SpecialVisualizationState ,
tags : UIEventSource < Record < string , string > > ,
args : string [ ] ,
feature : Feature ,
layer : LayerConfig
) : SvelteUIElement {
const isOpen = args [ 0 ] === "open"
const readonly = args [ 1 ] === "readonly" || args [ 1 ] === "yes"
const [ lon , lat ] = GeoOperations . centerpointCoordinates ( feature )
return new SvelteUIElement ( isOpen ? NearbyImages : NearbyImagesCollapsed , {
tags ,
state ,
lon ,
lat ,
feature ,
layer ,
2025-02-10 02:04:58 +01:00
linkable : ! readonly ,
2025-01-27 04:50:44 +01:00
} )
}
}
export class ImageVisualisations {
static initList ( ) : SpecialVisualizationSvelte [ ] {
return [
new NearbyImageVis ( ) ,
{
funcName : "image_carousel" ,
group : "images" ,
docs : "Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)" ,
args : [
{
name : "image_key" ,
2025-04-04 01:53:28 +02:00
defaultValue : AllImageProviders.defaultKeys.join ( ";" ) ,
2025-02-10 02:04:58 +01:00
doc : "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated " ,
} ,
2025-01-27 04:50:44 +01:00
] ,
needsUrls : AllImageProviders.apiUrls ,
constr : ( state , tags , args ) = > {
let imagePrefixes : string [ ] = undefined
if ( args . length > 0 ) {
2025-04-04 01:53:28 +02:00
imagePrefixes = [ ] . concat ( . . . args . map ( ( a ) = > a . split ( ";" ) ) )
2025-01-27 04:50:44 +01:00
}
const images = AllImageProviders . loadImagesFor ( tags , imagePrefixes )
2025-02-10 02:04:58 +01:00
const estimated = tags . mapD ( ( tags ) = >
AllImageProviders . estimateNumberOfImages ( tags , imagePrefixes )
)
2025-01-27 04:50:44 +01:00
return new SvelteUIElement ( ImageCarousel , { state , tags , images , estimated } )
2025-02-10 02:04:58 +01:00
} ,
2025-01-27 04:50:44 +01:00
} ,
{
funcName : "image_upload" ,
group : "images" ,
docs : "Creates a button where a user can upload an image to IMGUR" ,
needsUrls : [ Imgur . apiUrl , . . . Imgur . supportingUrls ] ,
args : [
{
2025-04-04 01:53:28 +02:00
name : "image_key" ,
2025-01-27 04:50:44 +01:00
doc : "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)" ,
2025-04-04 01:53:28 +02:00
defaultValue : "panoramax" ,
2025-02-10 02:04:58 +01:00
required : false ,
2025-01-27 04:50:44 +01:00
} ,
{
name : "label" ,
doc : "The text to show on the button" ,
2025-02-10 02:04:58 +01:00
required : false ,
2025-01-27 04:50:44 +01:00
} ,
{
name : "disable_blur" ,
doc : "If set to 'true' or 'yes', then face blurring will be disabled. To be used sparingly" ,
2025-02-10 02:04:58 +01:00
required : false ,
} ,
2025-01-27 04:50:44 +01:00
] ,
constr : ( state , tags , args , feature ) = > {
const targetKey = args [ 0 ] === "" ? undefined : args [ 0 ]
const noBlur = args [ 3 ] ? . toLowerCase ( ) ? . trim ( )
return new SvelteUIElement ( UploadImage , {
state ,
tags ,
targetKey ,
feature ,
labelText : args [ 1 ] ,
image : args [ 2 ] ,
2025-02-10 02:04:58 +01:00
noBlur : noBlur === "true" || noBlur === "yes" ,
2025-01-27 04:50:44 +01:00
} )
2025-02-10 02:04:58 +01:00
} ,
} ,
]
2025-01-27 04:50:44 +01:00
}
}