UX(nearby_features): place nearby panorama markers at nearly the right place

This commit is contained in:
Pieter Vander Vennet 2025-05-24 02:04:32 +02:00
parent 9135f1df6b
commit 79924acaf0
2 changed files with 23 additions and 6 deletions

View file

@ -10,11 +10,12 @@ import {
MultiPolygon, MultiPolygon,
Point, Point,
Polygon, Polygon,
Position, Position
} from "geojson" } from "geojson"
import { Tiles } from "../Models/TileRange" import { Tiles } from "../Models/TileRange"
import { Utils } from "../Utils" import { Utils } from "../Utils"
;("use strict")
("use strict")
export class GeoOperations { export class GeoOperations {
private static readonly _earthRadius: number = 6378137 private static readonly _earthRadius: number = 6378137
@ -106,7 +107,7 @@ export class GeoOperations {
* @param lonlat0 * @param lonlat0
* @param lonlat1 * @param lonlat1
*/ */
static distanceBetween(lonlat0: [number, number], lonlat1: [number, number] | Position) { static distanceBetween(lonlat0: [number, number] | Coord | Position, lonlat1: [number, number] | Position | Coord) {
return turf.distance(lonlat0, lonlat1, { units: "meters" }) return turf.distance(lonlat0, lonlat1, { units: "meters" })
} }

View file

@ -42,12 +42,26 @@ export class PhotoSphereViewerWrapper {
public calculatePitch(feature: Feature): number { public calculatePitch(feature: Feature): number {
const coors = this.imageInfo.geometry.coordinates const coors = this.imageInfo.geometry.coordinates
const distance = GeoOperations.distanceBetween( const distance = GeoOperations.distanceBetween(
<[number, number]>coors, coors,
GeoOperations.centerpointCoordinates(feature) GeoOperations.centerpointCoordinates(feature)
) )
// In: -pi/2 up to pi/2 // In: -pi/2 up to pi/2
const alpha = Math.atan(distance / 4) // in radians /*
. + Eye
. / |
. / PITCH |
. / | (Height = y = ~2m)
. / |
./ ALPHA |
+..... (x = distance) .... +
*/
const height = 3
// We want to know PITCH = 90 - alpha.
//
// tan(alpha) = height / distance (we rescale so that distance -> 1)
// alpha = atan(height / distance)
const alpha = Math.atan(height / distance) // in radians
const degrees = (alpha * 360) / (2 * Math.PI) const degrees = (alpha * 360) / (2 * Math.PI)
return -degrees return -degrees
} }
@ -86,6 +100,7 @@ export class PhotoSphereViewerWrapper {
const northOffs = imageInfo.properties.northOffset const northOffs = imageInfo.properties.northOffset
this.nearbyFeatures = nearbyFeatures this.nearbyFeatures = nearbyFeatures
this.clearHotspots() this.clearHotspots()
const centralImageLocation = this.imageInfo.geometry.coordinates
for (const f of nearbyFeatures ?? []) { for (const f of nearbyFeatures ?? []) {
if (f.properties.gotoPanorama?.properties?.url === this.imageInfo.properties.url) { if (f.properties.gotoPanorama?.properties?.url === this.imageInfo.properties.url) {
continue // This is the current panorama, no need to show it continue // This is the current panorama, no need to show it
@ -97,12 +112,13 @@ export class PhotoSphereViewerWrapper {
} else if (!isNaN(f.properties.pitch)) { } else if (!isNaN(f.properties.pitch)) {
pitch = f.properties.pitch pitch = f.properties.pitch
} }
const distance = Math.round(GeoOperations.distanceBetween(centralImageLocation, GeoOperations.centerpointCoordinates(f)))
this.viewer.addHotSpot( this.viewer.addHotSpot(
{ {
type: f.properties.gotoPanorama !== undefined ? "scene" : "info", type: f.properties.gotoPanorama !== undefined ? "scene" : "info",
yaw: (yaw - northOffs) % 360, yaw: (yaw - northOffs) % 360,
pitch, pitch,
text: f.properties.name, text: f.properties.name + " (" + distance + "m)",
clickHandlerFunc: () => { clickHandlerFunc: () => {
this.setPanorama(f.properties.gotoPanorama) this.setPanorama(f.properties.gotoPanorama)
}, },