【问题标题】:Mapping latitude and longitude to Canvas points in JavaScript在 JavaScript 中将纬度和经度映射到 Canvas 点
【发布时间】:2017-06-08 08:53:54
【问题描述】:

我正在编写一个 AR 应用程序,在该应用程序中,用户可以像这样从船长的角度看到一艘船

我想使用其他船只的坐标(如左边的那艘)在使用 Canvas 的图像顶部绘制船只。我遇到的问题是将纬度、经度映射到画布点。

我已经阅读过Haversine 和Bearing 公式,但我不知道如何使用它们来做我想做的事。我知道用户正在查看的船的纬度和经度,并尝试使用它们来计算另一艘船的 Canvas 点,但我无法让它工作。有什么想法吗?

【问题讨论】:

标签: javascript canvas html5-canvas location


【解决方案1】:

在相机的视野中寻找真实世界的对象。

这是可能的最简单的答案,因为有许多未知数会影响结果。

问题

图片说明了我所理解的问题。

我们有 3 艘船(找到解决方案所需的最少数量)标有红色 A、B、C。我们知道每艘船的经纬度。由于它们距离很近,因此无需校正因经度汇合造成的任何失真。

绿线代表相机的视野,图像通过镜头投影到 CCD 上(A 上方的绿线) twp 灰线然后投影到船下方的相机屏幕上。

三角剖分和三角形。

根据经度,我们可以找到每艘船到另一艘船的距离,从而得出三角形的边长。

var ships = {
    A : { lat : ?, long : ? },
    B : { lat : ?, long : ? },
    C : { lat : ?, long : ? },
}
var AB = Math.hypot(ships.A.lat - ships.B.lat, ships.A.long - ships.B.long);
var BC = Math.hypot(ships.C.lat - ships.B.lat, ships.C.long - ships.B.long);
var CA = Math.hypot(ships.A.lat - ships.C.lat, ships.A.long - ships.C.long);

插入三角形显示了如何在给定边长的情况下找到角的角度。

为此,我们追求角度pheta

var pheta = Math.acos(BC * BC - AB * AB + CA * CA) / (-2 * AB * CA));

相机的视野。

现在我们需要一些额外的信息。那是相机的视野(在图像中为绿线和红色 FOV)。您必须找到您正在使用的相机的这些详细信息。

典型的手机摄像头的焦距 (fl) 等效于 24-35 毫米,并且知道 CCD 的相对尺寸,您可以找到 FOVvar FOV = 2 * Math.atan((CCD.width / 2) / fl) 但这是有问题的,因为现代手机在10mm厚,CCD很小,实际尺寸是多少?

您可以使用一个漫长而复杂的过程来确定 FOV,而无需了解相机的内部尺寸,但很容易查看手机规格。

现在让我们假设相机的 FOV 为 67 度(1.17 弧度)。如果相机的分辨率为1280,我们忽略镜头畸变,保持相机垂直且与目标处于同一水平,我们可以通过它们之间的角度计算两艘船之间的像素距离。

var FOV = 1.17; // radians the Field of View of the camera
var pixels = (1.17 / 1280) * pheta; // 1280 is horizontal resolution of display

所以现在我们在相机上获得了两艘船之间的像素距离。假设它们适合相机,我们会遗漏另一项重要信息。

轴承

我们需要知道相机指向哪个方向作为方位。只有当我们拥有它时,我们才能找到船只。因此,让我们假设手机上的 GPS 可以为您提供实时方位。我们需要的是其中一艘船的方位。

我必须深入挖掘我的档案才能找到它,它没有来源或参考,所以只能按原样提供。它所拥有的只是 Haversin,所以假设这是使用的方法。

在进一步挖掘之后,我发现了可能源自 Calculate distance, bearing and more between Latitude/Longitude points 的原始源代码的引用

function deg2rad(angle) {  return angle * 0.017453292519943295 }
function rad2deg(angle) {  return angle / 0.017453292519943295 }
//return bearing in radians.
function getBearing(lat1,lon1,lat2,lon2){
    var earth = 6371e3; 
    var lat1 = lat1.toRadians();
    var lat2 = lat2.toRadians();
    var lon1 = lon1.toRadians();
    var lon2 = lon2.toRadians();
    var latD = lat2-lat1;
    var lonD = lon2-lon1;
    var a = Math.sin(latD / 2) * Math.sin(latD / 2) +  Math.cos(lat1 ) * Math.cos(lat2) *  Math.sin(lonD / 2) * Math.sin(lonD / 2);
    var c = 2 * Math.atan2( Math.sqrt(a),  Math.sqrt(1-a) );
    return earth * c;
}

所以现在你可以从你那里得到其中一艘船的方位。使用它和你的方位来找出你和它之间的角度差异。

   var yourBearing = ?; // in radians
   var shipBBearing = getBearing(ships.A.lat, ships.A.long, ships.B.lat, ships.B.long);

现在得到角度差

   var shipBAt = yourBearing - shipBBearing

了解像素 FOV

   var shipBPixelsFromCenter = (FOV / 1280) * shipBAt;

   var shipBXpos = 1280 / 2 - shipBPixelsFromCenter;
   // and from above the dif in pixels between ships is
   var shipCXpos = shipBXpos + pixels.

完成了。

【讨论】:

  • 我会试试这个,并会尽快通知您,但在这一刻,我想说感谢您抽出宝贵时间给出如此详尽的答案!非常感谢!
  • @Jaimy 最后有点匆忙,没有校对,但现在回来,所以会再试一次,以确保我做的一切都正确。
  • 快速更新。到目前为止,我得到的 X 位置似乎是有意义的。只需要根据我的特定情况调整一些值。再次感谢您提供详细而详细的答案!真的很感激。
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多