给定(纬度,经度)点,距离和方位,如何获得新的经纬度
Posted
技术标签:
【中文标题】给定(纬度,经度)点,距离和方位,如何获得新的经纬度【英文标题】:Given point of (latitude,longitude), distance and bearing, How to get the new latitude and longitude 【发布时间】:2015-07-12 04:48:25 【问题描述】:我在网上找到了一段代码。它通过给定的纬度/经度点和距离计算最小边界矩形。
private static void GetlatLon(double LAT, double LON, double distance, double angle, out double newLon, out double newLat)
double dx = distance * 1000 * Math.Sin(angle * Math.PI / 180.0);
double dy = distance * 1000 * Math.Cos(angle * Math.PI / 180.0);
double ec = 6356725 + 21412 * (90.0 - LAT) / 90.0;
double ed = ec * Math.Cos(LAT * Math.PI / 180);
newLon = (dx / ed + LON * Math.PI / 180.0) * 180.0 / Math.PI;
newLat = (dy / ec + LAT * Math.PI / 180.0) * 180.0 / Math.PI;
public static void GetRectRange(double centorlatitude, double centorLogitude, double distance,
out double maxLatitude, out double minLatitude, out double maxLongitude, out double minLongitude)
GetlatLon(centorlatitude, centorLogitude, distance, 0, out temp, out maxLatitude);
GetlatLon(centorlatitude, centorLogitude, distance, 180, out temp, out minLatitude);
GetlatLon(centorlatitude, centorLogitude, distance, 90, out minLongitude, out temp);
GetlatLon(centorlatitude, centorLogitude, distance, 270, out maxLongitude, out temp);
double ec = 6356725 + 21412 * (90.0 - LAT) / 90.0; //why?
double ed = ec * Math.Cos(LAT * Math.PI / 180); // why?
dx / ed //why?
dy / ec //why?
6378137是赤道半径,6356725是极半径,21412 =6378137 -6356725。 从the link,我知道了一点意思。但是这四行,我不知道为什么。你能帮忙提供更多信息吗?你能帮我知道公式的推导吗?
来自the link,在“目标点给定距起点的距离和方位角”一节中,它给出了另一个公式来获得结果。公式的推导是什么?
从这个link ,我知道了Haversine 公式的推导,它非常有用。我不认为“目标点给定距起点的距离和方位角”部分中的公式只是Haversine的简单回归。
非常感谢!
【问题讨论】:
你有原始代码的链接吗?double ec = 6356725 + 21412 * (90.0 - LAT) / 90.0
看起来像是一个加权平均值来估计赤道和两极之间的地球半径。因此,如果您在极点上,则只需使用半径 = 6356725,如果您在赤道上,则半径 = 6378137(请注意赤道处更大)。因此,当您介于两者之间时,您需要估计半径。
double ed = ec * Math.Cos(LAT * Math.PI / 180)
将估计的地球半径乘以从度数转换为弧度的给定纬度。所以这只是一个修正术语。由于dx
和dy
是平面上的计算距离,ec
旨在校正地球的曲率。
【参考方案1】:
这是一个很好的例子,说明为什么注释您的代码会使其更具可读性和可维护性。从数学上讲,您正在查看以下内容:
双 ec = 6356725 + 21412 * (90.0 - LAT) / 90.0; //为什么?
这是一种偏心率的度量,以某种方式解释赤道隆起。 21412
如您所知,是赤道和极地之间地球半径的差异。 6356725
是极半径。 (90.0 - LAT) / 90.0
在赤道是1
,在极点是0
。该公式只是估计在任何给定纬度存在多少凸起。
double ed = ec * Math.Cos(LAT * Math.PI / 180); // 为什么?
(LAT * Math.PI / 180)
是纬度从度到弧度的转换。 cos (0) = 1
和cos(1) = 0
,所以在赤道,你应用了全部的偏心率,而在极地你没有应用。与上一行类似。
dx / ed //为什么?
dy / ec //为什么?
以上似乎是x
和y
方向上距离的分数增加,可归因于newLon
中使用的任何给定纬度/经度 处的凸起newLat
计算到达新位置。
我没有对您找到的代码 sn-p 进行任何研究,但从数学上讲,这就是正在发生的事情。希望这会引导您朝着正确的方向前进。
C 中的Haversine 示例
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double m2ft (double l) /* convert meters to feet */
return l/(1200.0/3937.0);
double ft2smi (double l) /* convert feet to statute miles*/
return l/5280.0;
double km2smi (double l) /* convert km to statute mi. */
return ft2smi(m2ft( l * 1000.0 ));
static const double deg2rad = 0.017453292519943295769236907684886;
static const double earth_rad_m = 6372797.560856;
typedef struct pointd
double lat;
double lon;
pointd;
/* Computes the arc, in radian, between two WGS-84 positions.
The result is equal to Distance(from,to)/earth_rad_m
= 2*asin(sqrt(h(d/earth_rad_m )))
where:
d is the distance in meters between 'from' and 'to' positions.
h is the haversine function: h(x)=sin²(x/2)
The haversine formula gives:
h(d/R) = h(from.lat-to.lat)+h(from.lon-to.lon)+cos(from.lat)*cos(to.lat)
http://en.wikipedia.org/wiki/Law_of_haversines
*/
double arcradians (const pointd *from, const pointd *to)
double latitudeArc = (from-> lat - to-> lat) * deg2rad;
double longitudeArc = (from-> lon - to-> lon) * deg2rad;
double latitudeH = sin (latitudeArc * 0.5);
latitudeH *= latitudeH;
double lontitudeH = sin (longitudeArc * 0.5);
lontitudeH *= lontitudeH;
double tmp = cos (from-> lat * deg2rad) * cos (to-> lat * deg2rad);
return 2.0 * asin (sqrt (latitudeH + tmp*lontitudeH));
/* Computes the distance, in meters, between two WGS-84 positions.
The result is equal to earth_rad_m*ArcInRadians(from,to)
*/
double dist_m (const pointd *from, const pointd *to)
return earth_rad_m * arcradians (from, to);
int main (int argc, char **argv)
if (argc < 5 )
fprintf (stderr, "Error: insufficient input, usage: %s (lat,lon) (lat,lon)\n", argv[0]);
return 1;
pointd points[2];
points[0].lat = strtod (argv[1], NULL);
points[0].lon = strtod (argv[2], NULL);
points[1].lat = strtod (argv[3], NULL);
points[1].lon = strtod (argv[4], NULL);
printf ("\nThe distance in meters from 1 to 2 (smi): %lf\n\n", km2smi (dist_m (&points[0], &points[1])/1000.0) );
return 0;
/* Results/Example.
./bin/gce 31.77 -94.61 31.44 -94.698
The distance in miles from Nacogdoches to Lufkin, Texas (smi): 23.387997 miles
*/
【讨论】:
谢谢大卫。从链接(movable-type.co.uk/scripts/latlong.html)中,在“目标点给定距离和距起点的方位”部分中,它给出了另一个公式来获得结果。公式的推导是什么?有没有类似链接(mathforum.org/library/drmath/view/51879.html)的网页,非常清楚地展示了Haversine公式。 Haversine 公式还不错。我想我有一个到 C 的端口。基本上在所有纬度/经度问题中,您都在处理 大圆距离(这只是地球表面上球面坐标系的一个奇特术语。)它这一切都源于地球上点a
和点b
之间的线根本不是线,而是弧。因此,您找到的距离是从a
到b
的弧 距离。 archlength = radius * angle
。这就是为什么您会看到三角,而 r
由于凸起而发生变化,这就是为什么您会看到 ec
、ed
调整。
也 "目标点给定距离和距起点的方位角" 等式是相同的公式,但你有 point1
和 point2
,而不是 point1
和 angle from north & arc length
作为您的初始条件。在这里,您已经有了距离,因此您无需查找距离,而是使用距离查找point2
。 (自从我导出球坐标方程以来已经有很多年了——在我再次做之前会更多——祝你好运:p
)【参考方案2】:
我假设6356725 与radius of the earth 有关。看看这个answer,也看看Haversine Formula。
【讨论】:
以上是关于给定(纬度,经度)点,距离和方位,如何获得新的经纬度的主要内容,如果未能解决你的问题,请参考以下文章