forked from MapComplete/MapComplete
chore: automated housekeeping...
This commit is contained in:
parent
79b6927b56
commit
42ded4c1b1
328 changed files with 4062 additions and 1284 deletions
|
|
@ -35,7 +35,9 @@
|
|||
export let attributionFormat: "minimal" | "medium" | "large" = "medium"
|
||||
let previewedImage: UIEventSource<Partial<ProvidedImage>> = MenuState.previewedImage
|
||||
export let canZoom = previewedImage !== undefined
|
||||
export let nearbyFeatures: Feature<Geometry, HotspotProperties>[] | Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
export let nearbyFeatures:
|
||||
| Feature<Geometry, HotspotProperties>[]
|
||||
| Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
|
||||
let loaded = false
|
||||
let showBigPreview = new UIEventSource(false)
|
||||
|
|
@ -49,7 +51,7 @@
|
|||
previewedImage.addCallbackAndRun((previewedImage) => {
|
||||
showBigPreview.set(
|
||||
previewedImage !== undefined &&
|
||||
(previewedImage?.id ?? previewedImage?.url) === (image.id ?? image.url)
|
||||
(previewedImage?.id ?? previewedImage?.url) === (image.id ?? image.url)
|
||||
)
|
||||
})
|
||||
)
|
||||
|
|
@ -67,16 +69,15 @@
|
|||
type: "Feature",
|
||||
properties: {
|
||||
id: image.id,
|
||||
rotation: image.rotation
|
||||
rotation: image.rotation,
|
||||
},
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [image.lon, image.lat]
|
||||
}
|
||||
coordinates: [image.lon, image.lat],
|
||||
},
|
||||
}
|
||||
state?.geocodedImages.set([f])
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<Popup shown={showBigPreview} bodyPadding="p-0" dismissable={true}>
|
||||
|
|
@ -135,10 +136,12 @@
|
|||
/>
|
||||
|
||||
{#if image.isSpherical}
|
||||
<div class="absolute top-0 left-0 w-full h-full flex justify-center items-center pointer-events-none">
|
||||
<div class="bg-black opacity-50 rounded-full p-[3.25rem]">
|
||||
<div class="w-0 h-0 relative flex items-center justify-center">
|
||||
<Panorama360 class="absolute w-16 h-16" color="#ffffff" />
|
||||
<div
|
||||
class="pointer-events-none absolute left-0 top-0 flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<div class="rounded-full bg-black p-[3.25rem] opacity-50">
|
||||
<div class="relative flex h-0 w-0 items-center justify-center">
|
||||
<Panorama360 class="absolute h-16 w-16" color="#ffffff" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -157,7 +160,6 @@
|
|||
<ImageAttribution {image} {attributionFormat} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:else if image.status === "hidden"}
|
||||
<div class="subtle">This image has been reported</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@
|
|||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: GeoOperations.centerpointCoordinates(feature)
|
||||
coordinates: GeoOperations.centerpointCoordinates(feature),
|
||||
},
|
||||
properties: {
|
||||
name: layer?.title?.GetRenderValue(feature.properties)?.Subs(feature.properties)?.txt ?? feature?.properties?.name,
|
||||
focus: true
|
||||
}
|
||||
name:
|
||||
layer?.title?.GetRenderValue(feature.properties)?.Subs(feature.properties)?.txt ??
|
||||
feature?.properties?.name,
|
||||
focus: true,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
export let image: Partial<ProvidedImage> & { id: string; url: string }
|
||||
export let clss: string = undefined
|
||||
export let nearbyFeatures: Feature<Geometry, HotspotProperties>[] | Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
export let nearbyFeatures:
|
||||
| Feature<Geometry, HotspotProperties>[]
|
||||
| Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
|
||||
let isLoaded = new UIEventSource(false)
|
||||
console.log(">>> slots are", $$slots)
|
||||
|
|
@ -37,17 +39,17 @@
|
|||
</div>
|
||||
|
||||
{#if $$slots["dot-menu-actions"]}
|
||||
<DotMenu dotsPosition="top-0 left-0" dotsSize="w-8 h-8" hideBackground>
|
||||
<slot name="dot-menu-actions">
|
||||
<button
|
||||
class="no-image-background pointer-events-auto flex items-center"
|
||||
on:click={() => ImageProvider.offerImageAsDownload(image)}
|
||||
>
|
||||
<DownloadIcon class="h-6 w-6 px-2 opacity-100" />
|
||||
<Tr t={Translations.t.general.download.downloadImage} />
|
||||
</button>
|
||||
</slot>
|
||||
</DotMenu>
|
||||
<DotMenu dotsPosition="top-0 left-0" dotsSize="w-8 h-8" hideBackground>
|
||||
<slot name="dot-menu-actions">
|
||||
<button
|
||||
class="no-image-background pointer-events-auto flex items-center"
|
||||
on:click={() => ImageProvider.offerImageAsDownload(image)}
|
||||
>
|
||||
<DownloadIcon class="h-6 w-6 px-2 opacity-100" />
|
||||
<Tr t={Translations.t.general.download.downloadImage} />
|
||||
</button>
|
||||
</slot>
|
||||
</DotMenu>
|
||||
{/if}
|
||||
<div
|
||||
class="pointer-events-none absolute bottom-0 left-0 flex w-full flex-wrap items-end justify-between"
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@
|
|||
import type { Feature, Geometry, Point } from "geojson"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
|
||||
|
||||
export let nearbyFeatures: Feature<Geometry, HotspotProperties>[] | Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
export let nearbyFeatures:
|
||||
| Feature<Geometry, HotspotProperties>[]
|
||||
| Store<Feature<Geometry, HotspotProperties>[]> = []
|
||||
export let image: Partial<ProvidedImage>
|
||||
let panzoomInstance = undefined
|
||||
let panzoomEl: HTMLElement
|
||||
|
|
@ -34,17 +35,15 @@
|
|||
if (Array.isArray(nearbyFeatures)) {
|
||||
viewer.setNearbyFeatures(nearbyFeatures)
|
||||
} else {
|
||||
nearbyFeatures.addCallbackAndRunD(feats => {
|
||||
nearbyFeatures.addCallbackAndRunD((feats) => {
|
||||
viewer.setNearbyFeatures(feats)
|
||||
})
|
||||
}
|
||||
isLoaded.set(true)
|
||||
|
||||
}
|
||||
|
||||
$: {
|
||||
if (image.isSpherical) {
|
||||
|
||||
initPhotosphere()
|
||||
} else if (panzoomEl) {
|
||||
panzoomInstance = panzoom(panzoomEl, {
|
||||
|
|
@ -52,7 +51,7 @@
|
|||
boundsPadding: 0.49,
|
||||
minZoom: 0.1,
|
||||
maxZoom: 25,
|
||||
initialZoom: 1.0
|
||||
initialZoom: 1.0,
|
||||
})
|
||||
} else {
|
||||
panzoomInstance?.dispose()
|
||||
|
|
@ -61,17 +60,17 @@
|
|||
</script>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="./css/pannellum.css">
|
||||
<link rel="stylesheet" href="./css/pannellum.css" />
|
||||
</head>
|
||||
{#if image.isSpherical}
|
||||
<div bind:this={viewerEl} class="w-full h-full" />
|
||||
<div bind:this={viewerEl} class="h-full w-full" />
|
||||
{:else}
|
||||
<img
|
||||
bind:this={panzoomEl}
|
||||
class="panzoom-image h-fit max-w-fit"
|
||||
on:load={() => {
|
||||
isLoaded?.setData(true)
|
||||
}}
|
||||
isLoaded?.setData(true)
|
||||
}}
|
||||
src={image.url_hd ?? image.url}
|
||||
/>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
export let linkable = true
|
||||
let targetValue = Object.values(image.osmTags)[0]
|
||||
let isLinked = new UIEventSource(Object.values(tags.data).some((v) => targetValue === v))
|
||||
isLinked.addCallbackAndRun(linked => {
|
||||
isLinked.addCallbackAndRun((linked) => {
|
||||
if (linked) {
|
||||
MenuState.previewedImage.set(undefined)
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
provider: AllImageProviders.byName(image.provider),
|
||||
date: new Date(image.date),
|
||||
id: Object.values(image.osmTags)[0],
|
||||
isSpherical: image.details.isSpherical
|
||||
isSpherical: image.details.isSpherical,
|
||||
}
|
||||
|
||||
async function applyLink(isLinked: boolean) {
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
if (isLinked) {
|
||||
const action = new LinkImageAction(currentTags.id, key, url, tags, {
|
||||
theme: tags.data._orig_theme ?? state.theme.id,
|
||||
changeType: "link-image"
|
||||
changeType: "link-image",
|
||||
})
|
||||
await state.changes.applyAction(action)
|
||||
} else {
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
if (v === url) {
|
||||
const action = new ChangeTagAction(currentTags.id, new Tag(k, ""), currentTags, {
|
||||
theme: tags.data._orig_theme ?? state.theme.id,
|
||||
changeType: "remove-image"
|
||||
changeType: "remove-image",
|
||||
})
|
||||
state.changes.applyAction(action)
|
||||
}
|
||||
|
|
@ -99,9 +99,7 @@
|
|||
attributionFormat="minimal"
|
||||
>
|
||||
<svelte:fragment slot="dot-menu-actions">
|
||||
|
||||
<LoginToggle {state} silentFail={true} hiddenFail={true}>
|
||||
|
||||
{#if linkable}
|
||||
<label>
|
||||
<input bind:checked={$isLinked} type="checkbox" />
|
||||
|
|
@ -110,7 +108,6 @@
|
|||
{/if}
|
||||
</LoginToggle>
|
||||
</svelte:fragment>
|
||||
|
||||
</AttributedImage>
|
||||
<LoginToggle {state} silentFail={true}>
|
||||
{#if linkable}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@
|
|||
(pics: P4CPicture[]) =>
|
||||
pics
|
||||
.filter(
|
||||
(p: P4CPicture) =>
|
||||
!loadedImages.data.has(p.pictureUrl) // We don't show any image which is already linked
|
||||
(p: P4CPicture) => !loadedImages.data.has(p.pictureUrl) // We don't show any image which is already linked
|
||||
)
|
||||
.slice(0, 25),
|
||||
[loadedImages]
|
||||
|
|
@ -60,15 +59,15 @@
|
|||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [p4c.coordinates.lng, p4c.coordinates.lat]
|
||||
coordinates: [p4c.coordinates.lng, p4c.coordinates.lat],
|
||||
},
|
||||
properties: <PanoramaView>{
|
||||
id: p4c.pictureUrl,
|
||||
url: p4c.pictureUrl,
|
||||
northOffset: p4c.direction,
|
||||
rotation: p4c.direction,
|
||||
spherical: p4c.details.isSpherical ? "yes" : "no"
|
||||
}
|
||||
spherical: p4c.details.isSpherical ? "yes" : "no",
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
@ -80,14 +79,14 @@
|
|||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [s.coordinates.lng, s.coordinates.lat]
|
||||
coordinates: [s.coordinates.lng, s.coordinates.lat],
|
||||
},
|
||||
properties: {
|
||||
id: s.pictureUrl,
|
||||
selected: "yes",
|
||||
rotation: s.direction
|
||||
}
|
||||
}
|
||||
rotation: s.direction,
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
|
|
@ -112,7 +111,7 @@
|
|||
rotation: state.mapProperties.rotation,
|
||||
pitch: state.mapProperties.pitch,
|
||||
zoom: new UIEventSource<number>(16),
|
||||
location: new UIEventSource({ lon, lat })
|
||||
location: new UIEventSource({ lon, lat }),
|
||||
})
|
||||
|
||||
const geocodedImageLayer = new LayerConfig(<LayerConfigJson>geocoded_image)
|
||||
|
|
@ -123,7 +122,7 @@
|
|||
onClick: (feature) => {
|
||||
console.log("CLicked:", feature.properties)
|
||||
highlighted.set(feature.properties.id)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
ShowDataLayer.showMultipleLayers(map, new StaticFeatureSource([feature]), state.theme.layers)
|
||||
|
|
@ -146,24 +145,29 @@
|
|||
layer: geocodedImageLayer,
|
||||
onClick: (feature) => {
|
||||
highlighted.set(feature.properties.id)
|
||||
}
|
||||
},
|
||||
})
|
||||
let nearbyFeatures: Store<Feature[]> = asFeatures.map(nearbyPoints => {
|
||||
return [{
|
||||
type: "Feature",
|
||||
geometry: { type: "Point", coordinates: GeoOperations.centerpointCoordinates(feature) },
|
||||
properties: {
|
||||
name: layer.title?.GetRenderValue(feature.properties).Subs(feature.properties).txt,
|
||||
focus: true
|
||||
}
|
||||
}, ...nearbyPoints.filter(p => p.properties.spherical === "yes").map(f => ({
|
||||
...f, properties: {
|
||||
name: "Nearby panorama",
|
||||
pitch: "auto",
|
||||
type: "scene",
|
||||
gotoPanorama: f
|
||||
}
|
||||
}))
|
||||
let nearbyFeatures: Store<Feature[]> = asFeatures.map((nearbyPoints) => {
|
||||
return [
|
||||
{
|
||||
type: "Feature",
|
||||
geometry: { type: "Point", coordinates: GeoOperations.centerpointCoordinates(feature) },
|
||||
properties: {
|
||||
name: layer.title?.GetRenderValue(feature.properties).Subs(feature.properties).txt,
|
||||
focus: true,
|
||||
},
|
||||
},
|
||||
...nearbyPoints
|
||||
.filter((p) => p.properties.spherical === "yes")
|
||||
.map((f) => ({
|
||||
...f,
|
||||
properties: {
|
||||
name: "Nearby panorama",
|
||||
pitch: "auto",
|
||||
type: "scene",
|
||||
gotoPanorama: f,
|
||||
},
|
||||
})),
|
||||
]
|
||||
})
|
||||
|
||||
|
|
@ -204,7 +208,16 @@
|
|||
selected.set(undefined)
|
||||
}}
|
||||
>
|
||||
<LinkableImage {tags} {image} {state} {feature} {layer} {linkable} {highlighted} {nearbyFeatures} />
|
||||
<LinkableImage
|
||||
{tags}
|
||||
{image}
|
||||
{state}
|
||||
{feature}
|
||||
{layer}
|
||||
{linkable}
|
||||
{highlighted}
|
||||
{nearbyFeatures}
|
||||
/>
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,40 +13,45 @@
|
|||
export let imageArguments: ImageUploadArguments
|
||||
let confirmDelete = new UIEventSource(false)
|
||||
|
||||
|
||||
function del() {
|
||||
queue.delete(imageArguments)
|
||||
}
|
||||
|
||||
const t = Translations.t
|
||||
let src = undefined
|
||||
try{
|
||||
|
||||
try {
|
||||
src = URL.createObjectURL(imageArguments.blob)
|
||||
}catch (e) {
|
||||
} catch (e) {
|
||||
console.error("Could not create an ObjectURL for blob", imageArguments.blob)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="low-interaction rounded border-interactive w-fit p-2 m-1 flex flex-col">
|
||||
|
||||
<img class="max-w-64 w-auto max-h-64 w-auto" {src} />
|
||||
{imageArguments.featureId} {imageArguments.layoutId}
|
||||
<button class="as-link self-end" on:click={() => {confirmDelete.set(true)}}>
|
||||
<div class="low-interaction border-interactive m-1 flex w-fit flex-col rounded p-2">
|
||||
<img class="max-h-64 w-auto w-auto max-w-64" {src} />
|
||||
{imageArguments.featureId}
|
||||
{imageArguments.layoutId}
|
||||
<button
|
||||
class="as-link self-end"
|
||||
on:click={() => {
|
||||
confirmDelete.set(true)
|
||||
}}
|
||||
>
|
||||
<TrashIcon class="w-4" />
|
||||
<Tr t={t.imageQueue.delete} />
|
||||
</button>
|
||||
<Popup shown={confirmDelete} dismissable={true}>
|
||||
<Page shown={confirmDelete}>
|
||||
<svelte:fragment slot="header">
|
||||
<TrashIcon class="w-8 m-1" />
|
||||
<TrashIcon class="m-1 w-8" />
|
||||
<Tr t={t.imageQueue.confirmDeleteTitle} />
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="flex flex-col ">
|
||||
|
||||
<div class="flex flex-col">
|
||||
<div class="flex justify-center">
|
||||
<img class="max-w-128 w-auto max-h-128 w-auto" src={URL.createObjectURL(imageArguments.blob)} />
|
||||
<img
|
||||
class="max-w-128 max-h-128 w-auto w-auto"
|
||||
src={URL.createObjectURL(imageArguments.blob)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
|
|
@ -54,8 +59,7 @@
|
|||
<Tr t={t.general.back} />
|
||||
</BackButton>
|
||||
<button on:click={() => del()} class="primary w-full">
|
||||
|
||||
<TrashIcon class="w-8 m-1" />
|
||||
<TrashIcon class="m-1 w-8" />
|
||||
<Tr t={t.imageQueue.confirmDelete} />
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@
|
|||
<Tr t={q.intro} />
|
||||
</div>
|
||||
|
||||
<UploadingImageCounter {state}/>
|
||||
<UploadingImageCounter {state} />
|
||||
|
||||
{#if $isUploading}
|
||||
<Loading />
|
||||
{:else}
|
||||
<button class="primary" on:click={() => state.imageUploadManager.uploadQueue()}>
|
||||
<ArrowPathIcon class="w-8 h-8 m-1" />
|
||||
<ArrowPathIcon class="m-1 h-8 w-8" />
|
||||
<Tr t={q.retryAll} />
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,14 @@
|
|||
errs.push(canBeUploaded.error)
|
||||
continue
|
||||
}
|
||||
await state?.imageUploadManager?.uploadImageAndApply(file, tags, targetKey, noBlur, feature, { ignoreGPS })
|
||||
await state?.imageUploadManager?.uploadImageAndApply(
|
||||
file,
|
||||
tags,
|
||||
targetKey,
|
||||
noBlur,
|
||||
feature,
|
||||
{ ignoreGPS }
|
||||
)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
state.reportError(e, "Could not upload image")
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
*/
|
||||
function getCount(input: Store<string[]>): Store<number> {
|
||||
if (featureId == "*") {
|
||||
return input.map(inp => inp.length)
|
||||
return input.map((inp) => inp.length)
|
||||
}
|
||||
return input.map(success => success.filter(item => item === featureId).length)
|
||||
return input.map((success) => success.filter((item) => item === featureId).length)
|
||||
}
|
||||
|
||||
let successfull = getCount(state.imageUploadManager.successfull)
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
const t = Translations.t.image
|
||||
const debugging = state.featureSwitches.featureSwitchIsDebugging
|
||||
let dismissed = 0
|
||||
failed.addCallbackAndRun(failed => {
|
||||
failed.addCallbackAndRun((failed) => {
|
||||
dismissed = Math.min(failed, dismissed)
|
||||
})
|
||||
</script>
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
{#if $pending - $failed === 1}
|
||||
<Tr t={t.upload.one.uploading} />
|
||||
{:else if $pending - $failed > 1}
|
||||
<Tr t={t.upload.multiple.uploading.Subs({count: $pending})} />
|
||||
<Tr t={t.upload.multiple.uploading.Subs({ count: $pending })} />
|
||||
{/if}
|
||||
</Loading>
|
||||
</div>
|
||||
|
|
@ -70,6 +70,6 @@
|
|||
{#if $successfull === 1}
|
||||
<Tr cls="thanks" t={t.upload.one.done} />
|
||||
{:else if $successfull > 1}
|
||||
<Tr cls="thanks" t={t.upload.multiple.done.Subs({count: $successfull})} />
|
||||
<Tr cls="thanks" t={t.upload.multiple.done.Subs({ count: $successfull })} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -4,38 +4,37 @@ import { Feature, Geometry, Point } from "geojson"
|
|||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import { HotspotProperties, PanoramaView } from "../../Logic/ImageProviders/ImageProvider"
|
||||
|
||||
|
||||
export class PhotoSphereViewerWrapper {
|
||||
|
||||
private imageInfo: Feature<Point, PanoramaView>
|
||||
private readonly viewer: Pannellum.Viewer
|
||||
private nearbyFeatures: Feature<Geometry, HotspotProperties>[] = []
|
||||
|
||||
constructor(container: HTMLElement, imageInfo: Feature<Point, PanoramaView>, nearbyFeatures?: Feature<Geometry, HotspotProperties>[]) {
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
imageInfo: Feature<Point, PanoramaView>,
|
||||
nearbyFeatures?: Feature<Geometry, HotspotProperties>[]
|
||||
) {
|
||||
this.imageInfo = imageInfo
|
||||
this.viewer = pannellum.viewer(container,
|
||||
<any>{
|
||||
default: {
|
||||
firstScene: imageInfo.properties.url,
|
||||
sceneFadeDuration: 250
|
||||
this.viewer = pannellum.viewer(container, <any>{
|
||||
default: {
|
||||
firstScene: imageInfo.properties.url,
|
||||
sceneFadeDuration: 250,
|
||||
},
|
||||
scenes: {
|
||||
[imageInfo.properties.url]: {
|
||||
type: "equirectangular",
|
||||
hfov: 110,
|
||||
panorama: imageInfo.properties.url,
|
||||
autoLoad: true,
|
||||
hotSpots: [],
|
||||
sceneFadeDuration: 250,
|
||||
compass: true,
|
||||
showControls: false,
|
||||
northOffset: imageInfo.properties.northOffset,
|
||||
horizonPitch: imageInfo.properties.pitchOffset,
|
||||
},
|
||||
scenes: {
|
||||
[imageInfo.properties.url]:
|
||||
{
|
||||
type: "equirectangular",
|
||||
hfov: 110,
|
||||
panorama: imageInfo.properties.url,
|
||||
autoLoad: true,
|
||||
hotSpots: [],
|
||||
sceneFadeDuration: 250,
|
||||
compass: true,
|
||||
showControls: false,
|
||||
northOffset: imageInfo.properties.northOffset,
|
||||
horizonPitch: imageInfo.properties.pitchOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
this.setNearbyFeatures(nearbyFeatures)
|
||||
}
|
||||
|
|
@ -43,12 +42,13 @@ export class PhotoSphereViewerWrapper {
|
|||
public calculatePitch(feature: Feature): number {
|
||||
const coors = this.imageInfo.geometry.coordinates
|
||||
const distance = GeoOperations.distanceBetween(
|
||||
<[number, number]>coors, GeoOperations.centerpointCoordinates(feature)
|
||||
<[number, number]>coors,
|
||||
GeoOperations.centerpointCoordinates(feature)
|
||||
)
|
||||
|
||||
// In: -pi/2 up to pi/2
|
||||
const alpha = Math.atan(distance / 4) // in radians
|
||||
const degrees = alpha * 360 / (2 * Math.PI)
|
||||
const degrees = (alpha * 360) / (2 * Math.PI)
|
||||
return -degrees
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ export class PhotoSphereViewerWrapper {
|
|||
this.viewer.addScene(imageInfo.properties.url, <any>{
|
||||
panorama: imageInfo.properties.url,
|
||||
northOffset: imageInfo.properties.northOffset,
|
||||
type: "equirectangular"
|
||||
type: "equirectangular",
|
||||
})
|
||||
|
||||
this.viewer.loadScene(imageInfo.properties.url, 0, imageInfo.properties.northOffset)
|
||||
|
|
@ -70,7 +70,8 @@ export class PhotoSphereViewerWrapper {
|
|||
}
|
||||
|
||||
private clearHotspots() {
|
||||
const hotspots = this.viewer.getConfig()["scenes"][this.imageInfo.properties.url].hotSpots ?? []
|
||||
const hotspots =
|
||||
this.viewer.getConfig()["scenes"][this.imageInfo.properties.url].hotSpots ?? []
|
||||
for (const hotspot of hotspots) {
|
||||
this.viewer.removeHotSpot(hotspot?.id, this.imageInfo.properties.url)
|
||||
}
|
||||
|
|
@ -95,20 +96,21 @@ export class PhotoSphereViewerWrapper {
|
|||
} else if (!isNaN(f.properties.pitch)) {
|
||||
pitch = f.properties.pitch
|
||||
}
|
||||
this.viewer.addHotSpot({
|
||||
type: f.properties.gotoPanorama !== undefined ? "scene" : "info",
|
||||
yaw: (yaw - northOffs) % 360,
|
||||
pitch,
|
||||
text: f.properties.name,
|
||||
clickHandlerFunc: () => {
|
||||
this.setPanorama(f.properties.gotoPanorama)
|
||||
}
|
||||
}, this.imageInfo.properties.url)
|
||||
this.viewer.addHotSpot(
|
||||
{
|
||||
type: f.properties.gotoPanorama !== undefined ? "scene" : "info",
|
||||
yaw: (yaw - northOffs) % 360,
|
||||
pitch,
|
||||
text: f.properties.name,
|
||||
clickHandlerFunc: () => {
|
||||
this.setPanorama(f.properties.gotoPanorama)
|
||||
},
|
||||
},
|
||||
this.imageInfo.properties.url
|
||||
)
|
||||
if (f.properties.focus) {
|
||||
this.viewer.setYaw(yaw - northOffs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue