javascript:纬度/经度、纬度1/经度1、方位、到x、y屏幕坐标的距离?

发布于 2024-09-08 03:14:49 字数 422 浏览 8 评论 0原文

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

真实数据:
纬度/经度(十进制)和海拔高度(米):
相机坐标:49.994249、8.66539、2
热点坐标:49.994163、8.665388、2

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

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

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

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

谢谢,
一月
janmartin AT diy-streetview DOT 组织

how to project a lat/lon hotspot onto an 360x180 degree panorama image?
Using javascript?

Real data:
lat/lon in decimal degrees and altitude in meters:
Camera coordinates: 49.994249, 8.66539, 2
Hotspot coordinates: 49.994163, 8.665388, 2

Distance camera to hotspot in meters: 9.55
Compass bearing camera to hotspot in degrees (0-360): 170
Image direction: 130 degrees (x middle of image) Is this needed at all?
Horizon is y middle of image.

Image size width: 1024, height: 512 pixel

What I need is the javascript code to determine the x,y pixel image coordinate of the hotspot.
0 is top left corner.

Accuracy is of no importance. Distance will always be smaller than 100 meters.

Thanks,
Jan
janmartin AT diy-streetview DOT org

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蒲公英的约定 2024-09-15 03:14:49

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

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

并且由于相机和热点都处于相同的高度,因此相对俯仰为零。

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

如果热点的高度与相机的高度不同,那么您必须使用一些简单的三角函数来计算俯仰角.:

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

因此,您的音高将是: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);

我希望这会有所帮助!

It looks like you have already done the hard part: converting the GPS coordinates into a relative bearing (and distance).

If the center of your 360° image points to 130° from North (assuming clockwise around the compass) and the bearing from the camera location and the hotspot is 170° from North, then it would appear that the hotspot is at 40° on your image, relative to the center of the image. And, since the image contains 360° and 1024px horizontally, then it would seem that the hotspot is located at 1024px / 360° * 40° = 114 px from the center of the image.

And since the camera and the hotspot are both at the same altitude, the relative pitch is zero.

Putting this together, you get the coordinates: 512 + 114, 256 + 0 = coordinates: 626, 256.

If the altitude of the hotspot were not the same as the camera, then you'd have to compute a pitch using some simple trig.:

First let us assume that ground distance = the distance at ground level between the camera location and the hotspot location. This will be the same regardless of the altitude of each.

So, your pitch would be: atan [ (hotspot altitude - camera altitude) / ground distance ].

For example, if you had a ground distance of 100m and the hotspot were at 10.75m with the camera still at 2m altitude, then you'd compute your pitch as:

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

To plot this on your panorama: 512px / 180° * 5° = 14px higher than the middle. Since the middle is at 256px and the top-left of the image is 0,0, then we'd subtract 14px from 256 to arrive at 242px.

Putting this all together into Javascript as you requested:

// 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);

I hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文