我在计算提供的第二点的纬度/经度以及计算第一点和距离的纬度/经度时仍然存在问题。
我在 Javascript 中找到了一种解决方案,我尝试转换为 Java。但结果不准确,看来我做错了什么。
public class Misc {
double EARTH_RADIUS_METERS= 6378.1 *1024;
private double toRad(double value) {
return value* (Math.PI/ 180);
}
private double toDeg (double value) {
return value* (180 / Math.PI);
}
/*-------------------------------------------------------------------------
* Given a starting lat/lon point on earth, distance (in meters)
* and bearing, calculates destination coordinates lat2/lon2.
*
* all params in radians
*-------------------------------------------------------------------------*/
GPoint destCoordsInRadians(double lat1, double lon1,
double distanceMeters, double bearing
/*,double* lat2, double* lon2*/)
{
//-------------------------------------------------------------------------
// Algorithm from http://www.geomidpoint.com/destination/calculation.html
// Algorithm also at http://www.movable-type.co.uk/scripts/latlong.html
//
// Spherical Earth Model
// 1. Let radiusEarth = 6372.7976 km or radiusEarth=3959.8728 miles
// 2. Convert distance to the distance in radians.
// dist = dist/radiusEarth
// 3. Calculate the destination coordinates.
// lat2 = asin(sin(lat1)*cos(dist) + cos(lat1)*sin(dist)*cos(brg))
// lon2 = lon1 + atan2(sin(brg)*sin(dist)*cos(lat1), cos(dist)-sin(lat1)*sin(lat2))
//-------------------------------------------------------------------------
double distRadians = distanceMeters / EARTH_RADIUS_METERS;
double lat2 = Math.asin( Math.sin(lat1) * Math.cos(distRadians) + Math.cos(lat1) * Math.sin(distRadians) * Math.cos(bearing));
double lon2 = lon1 + Math.atan2( Math.sin(bearing) * Math.sin(distRadians) * Math.cos(lat1),
Math.cos(distRadians) - Math.sin(lat1) * Math.sin(lat2) );
return new GPoint( lat2 , lon2 );
}
/*-------------------------------------------------------------------------
* Given a starting lat/lon point on earth, distance (in meters)
* and bearing, calculates destination coordinates lat2/lon2.
*
* all params in degrees
*-------------------------------------------------------------------------*/
GPoint destCoordsInDegrees(double lat1, double lon1,
double distanceMeters, double bearing/*,
double* lat2, double* lon2*/)
{
GPoint gPoint2=destCoordsInRadians(/*Deg_to_*/toRad(lat1), /*Deg_to_*/toRad(lon1),
distanceMeters, /*Deg_to_*/toRad(bearing)/*,
lat2, lon2*/);
gPoint2.lat = /*Rad_to_*/toDeg( gPoint2.lat );
gPoint2.lon = normalize180( /*Rad_to_*/toDeg( gPoint2.lon )) ;
return gPoint2;
}
/*-------------------------------------------------------------------------
* Given two lat/lon points on earth, calculates the heading
* from lat1/lon1 to lat2/lon2.
*
* lat/lon params in radians
* result in radians
*-------------------------------------------------------------------------*/
double headingInRadians(double lat1, double lon1, double lat2, double lon2)
{
//-------------------------------------------------------------------------
// Algorithm found at http://www.movable-type.co.uk/scripts/latlong.html
//
// Spherical Law of Cosines
//
// Formula: ? = atan2( sin(?lon) * cos(lat2),
// cos(lat1) * sin(lat2) ? sin(lat1) * cos(lat2) * cos(?lon) )
// JavaScript:
//
// 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 = Math.atan2(y, x).toDeg();
//-------------------------------------------------------------------------
double dLon = lon2 - lon1;
double y = Math.sin(dLon) * Math.cos(lat2);
double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
return Math.atan2(y, x);
}
/*-------------------------------------------------------------------------
* Given two lat/lon points on earth, calculates the heading
* from lat1/lon1 to lat2/lon2.
*
* lat/lon params in degrees
* result in degrees
*-------------------------------------------------------------------------*/
double headingInDegrees(double lat1, double lon1, double lat2, double lon2)
{
return /*Rad_to_*/toDeg( headingInRadians(/*Deg_to_*/toRad(lat1),
/*Deg_to_*/toRad(lon1),
/*Deg_to_*/toRad(lat2),
/*Deg_to_*/toRad(lon2)) );
}
// Normalize a heading in degrees to be within -179.999999° to 180.00000°
double normalize180(double heading)
{
while (true) {
if (heading <= -180) {
heading += 360;
} else if (heading > 180) {
heading -= 360;
} else {
return heading;
}
}
}
// Normalize a heading in degrees to be within -179.999999° to 180.00000°
float normalize180f(float heading)
{
while (true) {
if (heading <= -180) {
heading += 360;
} else if (heading > 180) {
heading -= 360;
} else {
return heading;
}
}
}
// Normalize a heading in degrees to be within 0° to 359.999999°
double normalize360(double heading)
{
while (true) {
if (heading < 0) {
heading += 360;
} else if (heading >= 360) {
heading -= 360;
} else {
return heading;
}
}
}
// Normalize a heading in degrees to be within 0° to 359.999999°
float normalize360f(float heading)
{
while (true) {
if (heading < 0) {
heading += 360;
} else if (heading >= 360) {
heading -= 360;
} else {
return heading;
}
}
}
}