0

如何将纬度/经度热点投影到 360x180 度全景图像上?
使用 javascript?

真实数据:
以十进制度为单位的纬度/经度和以米为单位的高度:
相机坐标:49.994249、8.66539、2
热点坐标:49.994163、8.665388、2

相机到热点的距离(以米为单位):9.55
罗盘方位相机到热点的度数(0-360):170
图像方向:130 度(x 图像中间) 这是否需要?
地平线是图像的 y 中间。

图片尺寸宽度:1024,高度:512像素

我需要的是确定热点的 x,y 像素图像坐标的 javascript 代码。
0 是左上角。

准确性并不重要。距离将始终小于 100 米。

谢谢,
Jan
janmartin AT diy-streetview DOT org

4

1 回答 1

0

看起来您已经完成了最困难的部分:将 GPS 坐标转换为相对方位(和距离)。

如果您的 360° 图像的中心指向与北方成 130°(假设围绕指南针顺时针方向)并且相机位置的方位和热点与北方成 170°,那么热点似乎在您的 40°图像,相对于图像的中心。而且,由于图像水平包含 360° 和 1024px,因此热点似乎位于距图像中心 1024px / 360° * 40° = 114 px 处。

而且由于相机和热点都在同一高度,因此相对俯仰为零。

把这些放在一起,你会得到坐标:512 + 114、256 + 0 = 坐标:626、256。

如果热点的高度与相机不同,那么您必须使用一些简单的触发来计算音高:

首先让我们假设ground distance= 相机位置和热点位置之间的地面距离。无论每个人的高度如何,这都是一样的。

所以,你的音调是:atan [(热点高度 - 相机高度)/地面距离]。

例如,如果您的地面距离为 100m,并且热点位于 10.75m 处,而相机仍处于 2m 高度,那么您将计算俯仰角为:

间距 = atan [ (10.75m - 2m) / 100m ] = atan ( 8.75m / 100m ) = atan (0.0875) = 5°

在全景图上绘制:512px / 180° * 5° = 比中间高 14px。由于中间是 256 像素,图像的左上角是 0,0,所以我们将从 256 中减去 14 像素,得到 242 像素。

按照您的要求将所有这些放在 Javascript 中:

// We'll use degrees, but this would be simpler if
// everything were computed in radians, since that
// is how the Math methods work.
function getRelativePitch(cameraAlt, hsAlt, groundDistance)
{
   var degPerRad = 180 / Math.PI;

   if (groundDistance == 0) { return 0.0; } // fringe case

   var rad = Math.atan( ( hsAlt - cameraAlt) / groundDistance );

   // Convert to degress
   return rad * degPerRad;
}

// Pretty simply this one.
function getRelativeHeading(cameraHeading, hsHeading)
{
   return hsHeading - cameraHeading;
}

var cameraHeading = 130; // degrees
var hotspotHeading = 170; // degrees
var cameraAltitude = 2; // meters
var hotspotAltitude = 10.75; // meters
var groundDistance = 100; // meters

var panoWidth = 1024; // pixels
var panoHeight = 512; // pixels

var panoRangeX = 360; // degrees
var panoRangeY = 180; // degrees

var relativeHeading = getRelativeHeading(cameraHeading, hotspotHeading);
var relativePitch   = getRelativePitch(cameraAltitude, hotspotAltitude, groundDistance);

// Now convert to pixels
var hotspotX = Math.round( panoWidth / 2 + panoWidth / panoRangeX * relativeHeading );
var hotspotY = Math.round( panoHeight / 2 - panoHeight / panoRangeY * relativePitch );

// Just in case we endup out of range
while (hotspotX < 0) { hotspotX += panoWidth; }
while (hotspotX > panoWidth) { hotspotX -= panoWidth; }

while (hotspotY < 0) { hotspotY += panoHeight; }
while (hotspotY > panoHeight) { hotspotY -= panoHeight; }

alert("Hotspot is at: " + hotspotX + ", " + hotspotY);

我希望这有帮助!

于 2010-09-10T08:42:33.200 回答