UX: stepwise search in panoramax: allow wider FOV when nearby

This commit is contained in:
Pieter Vander Vennet 2025-05-06 01:46:06 +02:00
parent 875b3a3ea8
commit 3f2e48e4aa
4 changed files with 65 additions and 34 deletions

8
package-lock.json generated
View file

@ -72,7 +72,7 @@
"osm-auth": "^2.6.0", "osm-auth": "^2.6.0",
"osmtogeojson": "^3.0.0-beta.5", "osmtogeojson": "^3.0.0-beta.5",
"pannellum": "^2.5.6", "pannellum": "^2.5.6",
"panoramax-js": "^0.4.11", "panoramax-js": "^0.4.12",
"panzoom": "^9.4.3", "panzoom": "^9.4.3",
"papaparse": "^5.5.2", "papaparse": "^5.5.2",
"pg": "^8.11.3", "pg": "^8.11.3",
@ -22012,9 +22012,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/panoramax-js": { "node_modules/panoramax-js": {
"version": "0.4.11", "version": "0.4.12",
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.4.11.tgz", "resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.4.12.tgz",
"integrity": "sha512-TrNSFMOb1nCFej+nzu0d7iGdWbToALvPkfWZdMi0l/yeQr/xj/r/ONCvSb98w8q7kAWaZnstVjs3VEC1zRqftg==", "integrity": "sha512-BFNMGFumMmBfL7QC3IQxgWjy1nr2AWrcNcQY9n1y0UGGNLrDxv9+i6EzuZ3slgGP+qvb7tKx8mqfZaN6U/O/4g==",
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {
"@ogcapi-js/features": "^1.1.1", "@ogcapi-js/features": "^1.1.1",

View file

@ -235,7 +235,7 @@
"osm-auth": "^2.6.0", "osm-auth": "^2.6.0",
"osmtogeojson": "^3.0.0-beta.5", "osmtogeojson": "^3.0.0-beta.5",
"pannellum": "^2.5.6", "pannellum": "^2.5.6",
"panoramax-js": "^0.4.11", "panoramax-js": "^0.4.12",
"panzoom": "^9.4.3", "panzoom": "^9.4.3",
"papaparse": "^5.5.2", "papaparse": "^5.5.2",
"pg": "^8.11.3", "pg": "^8.11.3",

View file

@ -8458,6 +8458,10 @@ svg.apply-fill path {
padding: 0.75rem; padding: 0.75rem;
} }
.sm\:p-4 {
padding: 1rem;
}
.sm\:p-5 { .sm\:p-5 {
padding: 1.25rem; padding: 1.25rem;
} }
@ -8757,6 +8761,10 @@ svg.apply-fill path {
padding: 1.5rem; padding: 1.5rem;
} }
.md\:p-8 {
padding: 2rem;
}
.md\:px-2 { .md\:px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;

View file

@ -8,7 +8,7 @@ import Constants from "../../Models/Constants"
import { Utils } from "../../Utils" import { Utils } from "../../Utils"
import { Point } from "geojson" import { Point } from "geojson"
import { Imgur } from "../ImageProviders/Imgur" import { Imgur } from "../ImageProviders/Imgur"
import { Panoramax, PanoramaxXYZ } from "panoramax-js/dist" import { ImageData, Panoramax, PanoramaxXYZ } from "panoramax-js/dist"
interface ImageFetcher { interface ImageFetcher {
/** /**
@ -181,36 +181,59 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
} }
} }
public async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> { private static convert(imageData: ImageData): P4CPicture {
const images = await this._panoramax.search({ const [lng, lat] = imageData.geometry.coordinates
place: [lon, lat], return {
place_distance: this._radius ?? 50, pictureUrl: imageData.assets.sd.href,
place_fov_tolerance: 180, coordinates: { lng, lat },
limit: 50,
})
return images.map((i) => { provider: "panoramax",
const [lng, lat] = i.geometry.coordinates direction: imageData.properties["view:azimuth"],
return { osmTags: {
pictureUrl: i.assets.sd.href, panoramax: imageData.id
coordinates: { lng, lat }, },
thumbUrl: imageData.assets.thumb.href,
provider: "panoramax", date: new Date(imageData.properties.datetime).getTime(),
direction: i.properties["view:azimuth"], license: imageData.properties["geovisio:license"],
osmTags: { author: imageData.providers.at(-1).name,
panoramax: i.id, detailsUrl: imageData.id,
}, details: {
thumbUrl: i.assets.thumb.href, isSpherical:
date: new Date(i.properties.datetime).getTime(), imageData.properties["exif"]["Xmp.GPano.ProjectionType"] === "equirectangular"
license: i.properties["geovisio:license"],
author: i.providers.at(-1).name,
detailsUrl: i.id,
details: {
isSpherical:
i.properties["exif"]["Xmp.GPano.ProjectionType"] === "equirectangular",
},
} }
}) }
}
public async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> {
const radiusSettings = [{
place_fov_tolerance: 180,
radius: 15
}, {
place_fov_tolerance: 180,
radius: 25
}, {
place_fov_tolerance: 90,
radius: 50
}]
const promises: Promise<ImageData[]>[] = []
const maxRadius = this._radius
let prevRadius = 0
for (const radiusSetting of radiusSettings) {
const promise = this._panoramax.search({
place: [lon, lat],
place_distance: [prevRadius, Math.min(maxRadius, radiusSetting.radius)],
place_fov_tolerance: radiusSetting.place_fov_tolerance,
limit: 50
})
promises.push(promise)
prevRadius = radiusSetting.radius
if (radiusSetting.radius >= maxRadius) {
break
}
}
const images = await Promise.all(promises)
return [].concat(...images).map((i) => ImagesFromPanoramaxFetcher.convert(i))
} }
} }