给定点(纬度,经度),距离和方位角,如何得到新的经纬度
Given point of (latitude,longitude), distance and bearing, How to get the new latitude and longitude
我在网上找到了一段代码。它通过给定的 lat/lon 点和距离计算最小边界矩形。
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开始,在"Destination point given distance and bearing from start point"部分给出了另一个计算结果的公式。公式的推导是什么?
由此link知道了Haversine Formula的推导,很有参考意义。我不认为 "Destination point given distance and bearing from start point" 部分的公式只是 Haversine 的简单反转。
非常感谢!
我假设 6356725 has something to do with the radius of the earth. Check out this answer, and also take a look at the Haversine Formula。
这是一个很好的例子,说明为什么对代码进行注释会使其更具可读性和可维护性。从数学上讲,您正在查看以下内容:
double ec = 6356725 + 21412 * (90.0 - LAT) / 90.0; //why?
这是一种偏心率的测量方法,以某种方式解释赤道隆起。 21412
如您所知,是赤道和极地之间的地球半径差。 6356725
是极半径。 (90.0 - LAT) / 90.0
在赤道是1
,在极点是0
。该公式只是估计在任何给定纬度上存在多少凸起。
double ed = ec * Math.Cos(LAT * Math.PI / 180); // why?
(LAT * Math.PI / 180)
是纬度从度数到弧度的转换。 cos (0) = 1
和 cos(1) = 0
,因此在赤道,您应用了全部偏心率,而在极点,您应用了 none。与上一行类似。
dx / ed //why?
dy / ec //why?
以上似乎是 x
和 y
方向距离的分数增加,这是由于任何给定 lat/lon[=40 处的凸起造成的=] 用于 newLon
newLat
计算以到达新位置。
我没有对您找到的代码片段进行任何研究,但从数学上讲,这就是正在发生的事情。希望这会引导您朝着正确的方向前进。
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
*/
我在网上找到了一段代码。它通过给定的 lat/lon 点和距离计算最小边界矩形。
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开始,在"Destination point given distance and bearing from start point"部分给出了另一个计算结果的公式。公式的推导是什么?
由此link知道了Haversine Formula的推导,很有参考意义。我不认为 "Destination point given distance and bearing from start point" 部分的公式只是 Haversine 的简单反转。
非常感谢!
我假设 6356725 has something to do with the radius of the earth. Check out this answer, and also take a look at the Haversine Formula。
这是一个很好的例子,说明为什么对代码进行注释会使其更具可读性和可维护性。从数学上讲,您正在查看以下内容:
double ec = 6356725 + 21412 * (90.0 - LAT) / 90.0; //why?
这是一种偏心率的测量方法,以某种方式解释赤道隆起。 21412
如您所知,是赤道和极地之间的地球半径差。 6356725
是极半径。 (90.0 - LAT) / 90.0
在赤道是1
,在极点是0
。该公式只是估计在任何给定纬度上存在多少凸起。
double ed = ec * Math.Cos(LAT * Math.PI / 180); // why?
(LAT * Math.PI / 180)
是纬度从度数到弧度的转换。 cos (0) = 1
和 cos(1) = 0
,因此在赤道,您应用了全部偏心率,而在极点,您应用了 none。与上一行类似。
dx / ed //why?
dy / ec //why?
以上似乎是 x
和 y
方向距离的分数增加,这是由于任何给定 lat/lon[=40 处的凸起造成的=] 用于 newLon
newLat
计算以到达新位置。
我没有对您找到的代码片段进行任何研究,但从数学上讲,这就是正在发生的事情。希望这会引导您朝着正确的方向前进。
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
*/