使用两个经度/纬度点获取方向(指南针)
Posted
技术标签:
【中文标题】使用两个经度/纬度点获取方向(指南针)【英文标题】:Get direction (compass) with two longitude/latitude points 【发布时间】:2012-01-20 03:04:22 【问题描述】:我正在为移动设备开发“指南针”。我有以下几点:
point 1 (current location): Latitude = 47.2246, Longitude = 8.8257
point 2 (target location): Latitude = 50.9246, Longitude = 10.2257
我还有以下信息(来自我的安卓手机):
The compass-direction in degree, which bears to the north.
For example, when I direct my phone to north, I get 0°
如何创建一个“类似指南针”的箭头来显示指向该点的方向?
这有数学问题吗?
编辑:好的,我找到了解决方案,它看起来像这样:
/**
* Params: lat1, long1 => Latitude and Longitude of current point
* lat2, long2 => Latitude and Longitude of target point
*
* headX => x-Value of built-in phone-compass
*
* Returns the degree of a direction from current point to target point
*
*/
function getDegrees(lat1, long1, lat2, long2, headX)
var dLat = toRad(lat2-lat1);
var dLon = toRad(lon2-lon1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) -
Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
var brng = toDeg(Math.atan2(y, x));
// fix negative degrees
if(brng<0)
brng=360-Math.abs(brng);
return brng - headX;
【问题讨论】:
不要发布连你都不清楚的解决方案。 @Sameer 解决方案有什么问题?如果没有其他人发布一个,我可以成为一个。仅供参考,如果其他人需要它。为那个“原因”投了反对票。看不懂。 @eav 你创建的 toRad 函数是什么样的? @gohnjanotis: 背后没那么神奇 -> ***.com/questions/135909/… 函数声明有 long1 和 long2 但在函数中使用时它们是 lon1 和 lon2。 【参考方案1】:O忘了说我最终找到了答案。该应用程序用于确定运输车辆的指南针方向及其目的地。本质上,用于获取地球曲率、找到角度/罗盘读数,然后将该角度与通用罗盘值匹配的花哨数学。您当然可以保留 compassReading 并将其应用为图像的旋转量。请注意,这是车辆到终点(公共汽车站)方向的平均确定,这意味着它无法知道道路在做什么(因此这可能最适用于飞机或滚轮德比)。
//example obj data containing lat and lng points
//stop location - the radii end point
endpoint.lat = 44.9631;
endpoint.lng = -93.2492;
//bus location from the southeast - the circle center
startpoint.lat = 44.95517;
startpoint.lng = -93.2427;
function vehicleBearing(endpoint, startpoint)
endpoint.lat = x1;
endpoint.lng = y1;
startpoint.lat = x2;
startpoint.lng = y2;
var radians = getAtan2((y1 - y2), (x1 - x2));
function getAtan2(y, x)
return Math.atan2(y, x);
;
var compassReading = radians * (180 / Math.PI);
var coordNames = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"];
var coordIndex = Math.round(compassReading / 45);
if (coordIndex < 0)
coordIndex = coordIndex + 8
;
return coordNames[coordIndex]; // returns the coordinate value
即: 车辆轴承(mybus、busstation) 可能返回“NW”表示它向西北方向行驶
【讨论】:
@liquified,对不起,我无法理解为什么(compassReading / 45)正在完成。你能告诉我吗。谢谢。 45 是罗盘的 45 度间隔,与罗盘阵列(NSEW 等)的 9 个 coordName(人名)相关。将您的 compassReading 除以 45 可以在 360 度的范围内为您提供您的读数与其中一个间隔 (Math.round) 的接近程度。例如 360 / 45 给你 8 这是数组中的第 8 个索引或“N”。如果您只想要 NSEW,则可以通过除以 90 来修改它 @efwjames “与 9 个坐标名相关” - 45*8=360。您在 coordNames 数组中重复了两次“N”。请删除它。 我投票赞成这个答案,并给你我稍微缩短的版本(我喜欢数组和更多的风): const cardinals = ["N","NNE","NE","ENE" ,"E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"," N"]; const carDirect = (x0,y0, x1,y1) => Math.round( Math.atan2((x1-x0),(y1-y0)) * (8 / Math.PI) ); const cardIndex = (dir) => dir 【参考方案2】:我在数学 here 中找到了一些有用的 gps 坐标公式。 对于这种情况,这是我的解决方案
private double getDirection(double lat1, double lng1, double lat2, double lng2)
double PI = Math.PI;
double dTeta = Math.log(Math.tan((lat2/2)+(PI/4))/Math.tan((lat1/2)+(PI/4)));
double dLon = Math.abs(lng1-lng2);
double teta = Math.atan2(dLon,dTeta);
double direction = Math.round(Math.toDegrees(teta));
return direction; //direction in degree
【讨论】:
【参考方案3】:我无法很好地理解您的解决方案,计算斜率对我有用。 修改efwjames 和您的答案。这应该做 -
import math
def getDegrees(lat1, lon1, lat2, lon2,head):
dLat = math.radians(lat2-lat1)
dLon = math.radians(lon2-lon1)
bearing = math.degrees(math.atan2(dLon, dLat))
return head-bearing
【讨论】:
【参考方案4】:您需要计算起点和终点之间的欧几里得矢量,然后计算其角度(假设相对于正 X),这将是您想要旋转箭头的角度。
【讨论】:
或者你可以尽情地考虑地球的曲率 这是一个很好的答案描述,尝试提供一个真实的例子。 @liquified - 如果您查看帖子,即使在编辑之前,它也没有标记任何语言,并且提出的问题是:Is there a mathematic-problem for this?
。也没有提供代码,除了math
标签之外,也没有其他迹象表明 OP 是否想通过实数三角法或复数三角法来解决它(在许多中)。鉴于问题的模棱两可的参数,我认为答案就足够了。以上是关于使用两个经度/纬度点获取方向(指南针)的主要内容,如果未能解决你的问题,请参考以下文章