javascript:lat / lon,lat1 / lon1,方位,到x的距离,y屏幕坐标?

时间:2010-07-04 10:36:08

标签: javascript screen latitude-longitude panoramas cartesian

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

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

远程摄像机到热点的距离:9.55
罗盘轴承摄像机到热点的度数(0-360):170
图像方向:130度(图像的中间)是否需要它? 地平线是图像的中间部分。

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

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

准确性并不重要。距离总是小于100米。

谢谢,

janmartin AT diy-streetview DOT org

1 个答案:

答案 0 :(得分:0)

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

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

由于相机和热点都处于同一高度,因此相对音高为零。

将它们放在一起,得到坐标:512 + 114,256 + 0 =坐标:626,256。

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

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

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

例如,如果您的地面距离为100米且热点位于10.75米且相机仍处于2米高度,那么您将计算您的音高:

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

要在全景图上绘制:512px / 180°* 5°=比中间高14px。由于中间位于256px且图像的左上角为0,0,因此我们将从256减去14px以达到242px。

按照您的要求将所有内容整合到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);

我希望这有帮助!