I am wanting to find the distance between two different points. This I know can be accomplished with the great circle distance. http://www.meridianworlddata.com/Distance-calculation.asp
我想找到两个不同点之间的距离。我知道这可以用很大的圆距来完成。 http://www.meridianworlddata.com/Distance-calculation.asp
Once done, with a point and distance I would like to find the point that distance north, and that distance east in order to create a box around the point.
一旦完成,我想找到一个点和距离,我想找到距离北方的那个点,然后向东那个距离,以便在点周围创建一个方框。
10 个解决方案
#1
21
We've had some success using OpenMap to plot a lot of positional data. There's a LatLonPoint class that has some basic functionality, including distance.
我们在使用OpenMap绘制大量位置数据方面取得了一些成功。有一个LatLonPoint类,它有一些基本功能,包括距离。
#2
140
Here is a Java implementation of Haversine formula. I use this in a project to calculate distance in miles between lat/longs.
这是Haversine公式的Java实现。我在项目中使用它来计算纬度/长度之间的英里距离。
public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 3958.75; // miles (or 6371.0 kilometers)
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double sindLat = Math.sin(dLat / 2);
double sindLng = Math.sin(dLng / 2);
double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
* Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
return dist;
}
#3
43
Or you could use SimpleLatLng. Apache 2.0 licensed and used in one production system that I know of: mine.
或者你可以使用SimpleLatLng。 Apache 2.0在我知道的一个生产系统中获得许可并使用:我的。
Short story:
短篇故事:
I was searching for a simple geo library and couldn't find one to fit my needs. And who wants to write and test and debug these little geo tools over and over again in every application? There's got to be a better way!
我正在寻找一个简单的地理图书馆,找不到符合我需求的图书馆。谁想在每个应用程序中反复编写,测试和调试这些小地理工具?必须有更好的方法!
So SimpleLatLng was born as a way to store latitude-longitude data, do distance calculations, and create shaped boundaries.
因此,SimpleLatLng作为一种存储纬度 - 经度数据,进行距离计算和创建形状边界的方式而诞生。
I know I'm two years too late to help the original poster, but my aim is to help the people like me who find this question in a search. I would love to have some people use it and contribute to the testing and vision of this little lightweight utility.
我知道我已经两年太晚了,无法帮助原始海报,但我的目的是帮助像我一样在搜索中找到这个问题的人。我希望让一些人使用它,并为这个小型轻量级实用程序的测试和愿景做出贡献。
#4
11
For a more accurate distance (0.5mm) you can also use the Vincenty approximation:
要获得更精确的距离(0.5mm),您还可以使用Vincenty近似值:
/**
* Calculates geodetic distance between two points specified by latitude/longitude using Vincenty inverse formula
* for ellipsoids
*
* @param lat1
* first point latitude in decimal degrees
* @param lon1
* first point longitude in decimal degrees
* @param lat2
* second point latitude in decimal degrees
* @param lon2
* second point longitude in decimal degrees
* @returns distance in meters between points with 5.10<sup>-4</sup> precision
* @see <a href="http://www.movable-type.co.uk/scripts/latlong-vincenty.html">Originally posted here</a>
*/
public static double distVincenty(double lat1, double lon1, double lat2, double lon2) {
double a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params
double L = Math.toRadians(lon2 - lon1);
double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1)));
double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2)));
double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
double sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM;
double lambda = L, lambdaP, iterLimit = 100;
do {
sinLambda = Math.sin(lambda);
cosLambda = Math.cos(lambda);
sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda)
+ (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
if (sinSigma == 0)
return 0; // co-incident points
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = Math.atan2(sinSigma, cosSigma);
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
cosSqAlpha = 1 - sinAlpha * sinAlpha;
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
if (Double.isNaN(cos2SigmaM))
cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)
double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
lambdaP = lambda;
lambda = L + (1 - C) * f * sinAlpha
* (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
} while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
if (iterLimit == 0)
return Double.NaN; // formula failed to converge
double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
double deltaSigma = B
* sinSigma
* (cos2SigmaM + B
/ 4
* (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM
* (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
double dist = b * A * (sigma - deltaSigma);
return dist;
}
This code was freely adapted from http://www.movable-type.co.uk/scripts/latlong-vincenty.html
此代码可从http://www.movable-type.co.uk/scripts/latlong-vincenty.html免费改编
#5
6
Corrected Haversine Distance formula....
修正了Haversine距离公式....
public static double HaverSineDistance(double lat1, double lng1, double lat2, double lng2)
{
// mHager 08-12-2012
// http://en.wikipedia.org/wiki/Haversine_formula
// Implementation
// convert to radians
lat1 = Math.toRadians(lat1);
lng1 = Math.toRadians(lng1);
lat2 = Math.toRadians(lat2);
lng2 = Math.toRadians(lng2);
double dlon = lng2 - lng1;
double dlat = lat2 - lat1;
double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return EARTH_RADIUS * c;
}
#6
2
http://www.movable-type.co.uk/scripts/latlong.html
http://www.movable-type.co.uk/scripts/latlong.html
public static Double distanceBetweenTwoLocationsInKm(Double latitudeOne, Double longitudeOne, Double latitudeTwo, Double longitudeTwo) {
if (latitudeOne == null || latitudeTwo == null || longitudeOne == null || longitudeTwo == null) {
return null;
}
Double earthRadius = 6371.0;
Double diffBetweenLatitudeRadians = Math.toRadians(latitudeTwo - latitudeOne);
Double diffBetweenLongitudeRadians = Math.toRadians(longitudeTwo - longitudeOne);
Double latitudeOneInRadians = Math.toRadians(latitudeOne);
Double latitudeTwoInRadians = Math.toRadians(latitudeTwo);
Double a = Math.sin(diffBetweenLatitudeRadians / 2) * Math.sin(diffBetweenLatitudeRadians / 2) + Math.cos(latitudeOneInRadians) * Math.cos(latitudeTwoInRadians) * Math.sin(diffBetweenLongitudeRadians / 2)
* Math.sin(diffBetweenLongitudeRadians / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (earthRadius * c);
}
#7
1
You can use the Java Geodesy Library for GPS, it uses the Vincenty's formulae which takes account of the earths surface curvature.
您可以使用Java Geodesy Library for GPS,它使用Vincenty的公式,该公式考虑了地球表面的曲率。
Implementation goes like this:
实现如下:
import org.gavaghan.geodesy.*;
...
GeodeticCalculator geoCalc = new GeodeticCalculator();
Ellipsoid reference = Ellipsoid.WGS84;
GlobalPosition pointA = new GlobalPosition(latitude, longitude, 0.0);
GlobalPosition userPos = new GlobalPosition(userLat, userLon, 0.0);
double distance = geoCalc.calculateGeodeticCurve(reference, userPos, pointA).getEllipsoidalDistance();
The resulting distance is in meters.
得到的距离以米为单位。
#8
1
I know that there are many answers, but in doing some research on this topic, I found that most answers here use the Haversine formula, but the Vincenty formula is actually more accurate. There was one post that adapted the calculation from a Javascript version, but it's very unwieldy. I found a version that is superior because:
我知道有很多答案,但在对这个主题进行一些研究时,我发现这里的大多数答案都使用了Haversine公式,但Vincenty公式实际上更准确。有一篇文章改编了Javascript版本的计算,但它非常笨拙。我找到了一个优越的版本,因为:
- It also has an open license.
- 它还有一个开放许可证。
- It uses OOP principles.
- 它使用OOP原则。
- It has greater flexibility to choose the ellipsoid you want to use.
- 它具有更大的灵活性来选择您想要使用的椭球。
- It has more methods to allow for different calculations in the future.
- 它有更多的方法可以在将来进行不同的计算。
- It is well documented.
- 这是有据可查的。
VincentyDistanceCalculator
#9
1
This method would help you find the distance between to geographic location in km.
此方法可帮助您找到以km为单位的地理位置之间的距离。
private double getDist(double lat1, double lon1, double lat2, double lon2)
{
int R = 6373; // radius of the earth in kilometres
double lat1rad = Math.toRadians(lat1);
double lat2rad = Math.toRadians(lat2);
double deltaLat = Math.toRadians(lat2-lat1);
double deltaLon = Math.toRadians(lon2-lon1);
double a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
Math.cos(lat1rad) * Math.cos(lat2rad) *
Math.sin(deltaLon/2) * Math.sin(deltaLon/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
return d;
}
#10
0
I typically use MATLAB with the Mapping Toolbox, and then use the code in my Java using MATLAB Builder JA. It makes my life a lot simpler. Given most schools have it for free student access, you can try it out (or get the trial version to get over your work).
我通常将MATLAB与Mapping Toolbox一起使用,然后使用MATLAB Builder JA在我的Java中使用代码。它让我的生活变得更加简单。鉴于大多数学校都有免费学生访问权限,您可以尝试(或获得试用版来完成您的工作)。
#1
21
We've had some success using OpenMap to plot a lot of positional data. There's a LatLonPoint class that has some basic functionality, including distance.
我们在使用OpenMap绘制大量位置数据方面取得了一些成功。有一个LatLonPoint类,它有一些基本功能,包括距离。
#2
140
Here is a Java implementation of Haversine formula. I use this in a project to calculate distance in miles between lat/longs.
这是Haversine公式的Java实现。我在项目中使用它来计算纬度/长度之间的英里距离。
public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 3958.75; // miles (or 6371.0 kilometers)
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double sindLat = Math.sin(dLat / 2);
double sindLng = Math.sin(dLng / 2);
double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
* Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
return dist;
}
#3
43
Or you could use SimpleLatLng. Apache 2.0 licensed and used in one production system that I know of: mine.
或者你可以使用SimpleLatLng。 Apache 2.0在我知道的一个生产系统中获得许可并使用:我的。
Short story:
短篇故事:
I was searching for a simple geo library and couldn't find one to fit my needs. And who wants to write and test and debug these little geo tools over and over again in every application? There's got to be a better way!
我正在寻找一个简单的地理图书馆,找不到符合我需求的图书馆。谁想在每个应用程序中反复编写,测试和调试这些小地理工具?必须有更好的方法!
So SimpleLatLng was born as a way to store latitude-longitude data, do distance calculations, and create shaped boundaries.
因此,SimpleLatLng作为一种存储纬度 - 经度数据,进行距离计算和创建形状边界的方式而诞生。
I know I'm two years too late to help the original poster, but my aim is to help the people like me who find this question in a search. I would love to have some people use it and contribute to the testing and vision of this little lightweight utility.
我知道我已经两年太晚了,无法帮助原始海报,但我的目的是帮助像我一样在搜索中找到这个问题的人。我希望让一些人使用它,并为这个小型轻量级实用程序的测试和愿景做出贡献。
#4
11
For a more accurate distance (0.5mm) you can also use the Vincenty approximation:
要获得更精确的距离(0.5mm),您还可以使用Vincenty近似值:
/**
* Calculates geodetic distance between two points specified by latitude/longitude using Vincenty inverse formula
* for ellipsoids
*
* @param lat1
* first point latitude in decimal degrees
* @param lon1
* first point longitude in decimal degrees
* @param lat2
* second point latitude in decimal degrees
* @param lon2
* second point longitude in decimal degrees
* @returns distance in meters between points with 5.10<sup>-4</sup> precision
* @see <a href="http://www.movable-type.co.uk/scripts/latlong-vincenty.html">Originally posted here</a>
*/
public static double distVincenty(double lat1, double lon1, double lat2, double lon2) {
double a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params
double L = Math.toRadians(lon2 - lon1);
double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1)));
double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2)));
double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
double sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM;
double lambda = L, lambdaP, iterLimit = 100;
do {
sinLambda = Math.sin(lambda);
cosLambda = Math.cos(lambda);
sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda)
+ (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
if (sinSigma == 0)
return 0; // co-incident points
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = Math.atan2(sinSigma, cosSigma);
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
cosSqAlpha = 1 - sinAlpha * sinAlpha;
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
if (Double.isNaN(cos2SigmaM))
cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)
double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
lambdaP = lambda;
lambda = L + (1 - C) * f * sinAlpha
* (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
} while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
if (iterLimit == 0)
return Double.NaN; // formula failed to converge
double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
double deltaSigma = B
* sinSigma
* (cos2SigmaM + B
/ 4
* (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM
* (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
double dist = b * A * (sigma - deltaSigma);
return dist;
}
This code was freely adapted from http://www.movable-type.co.uk/scripts/latlong-vincenty.html
此代码可从http://www.movable-type.co.uk/scripts/latlong-vincenty.html免费改编
#5
6
Corrected Haversine Distance formula....
修正了Haversine距离公式....
public static double HaverSineDistance(double lat1, double lng1, double lat2, double lng2)
{
// mHager 08-12-2012
// http://en.wikipedia.org/wiki/Haversine_formula
// Implementation
// convert to radians
lat1 = Math.toRadians(lat1);
lng1 = Math.toRadians(lng1);
lat2 = Math.toRadians(lat2);
lng2 = Math.toRadians(lng2);
double dlon = lng2 - lng1;
double dlat = lat2 - lat1;
double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return EARTH_RADIUS * c;
}
#6
2
http://www.movable-type.co.uk/scripts/latlong.html
http://www.movable-type.co.uk/scripts/latlong.html
public static Double distanceBetweenTwoLocationsInKm(Double latitudeOne, Double longitudeOne, Double latitudeTwo, Double longitudeTwo) {
if (latitudeOne == null || latitudeTwo == null || longitudeOne == null || longitudeTwo == null) {
return null;
}
Double earthRadius = 6371.0;
Double diffBetweenLatitudeRadians = Math.toRadians(latitudeTwo - latitudeOne);
Double diffBetweenLongitudeRadians = Math.toRadians(longitudeTwo - longitudeOne);
Double latitudeOneInRadians = Math.toRadians(latitudeOne);
Double latitudeTwoInRadians = Math.toRadians(latitudeTwo);
Double a = Math.sin(diffBetweenLatitudeRadians / 2) * Math.sin(diffBetweenLatitudeRadians / 2) + Math.cos(latitudeOneInRadians) * Math.cos(latitudeTwoInRadians) * Math.sin(diffBetweenLongitudeRadians / 2)
* Math.sin(diffBetweenLongitudeRadians / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (earthRadius * c);
}
#7
1
You can use the Java Geodesy Library for GPS, it uses the Vincenty's formulae which takes account of the earths surface curvature.
您可以使用Java Geodesy Library for GPS,它使用Vincenty的公式,该公式考虑了地球表面的曲率。
Implementation goes like this:
实现如下:
import org.gavaghan.geodesy.*;
...
GeodeticCalculator geoCalc = new GeodeticCalculator();
Ellipsoid reference = Ellipsoid.WGS84;
GlobalPosition pointA = new GlobalPosition(latitude, longitude, 0.0);
GlobalPosition userPos = new GlobalPosition(userLat, userLon, 0.0);
double distance = geoCalc.calculateGeodeticCurve(reference, userPos, pointA).getEllipsoidalDistance();
The resulting distance is in meters.
得到的距离以米为单位。
#8
1
I know that there are many answers, but in doing some research on this topic, I found that most answers here use the Haversine formula, but the Vincenty formula is actually more accurate. There was one post that adapted the calculation from a Javascript version, but it's very unwieldy. I found a version that is superior because:
我知道有很多答案,但在对这个主题进行一些研究时,我发现这里的大多数答案都使用了Haversine公式,但Vincenty公式实际上更准确。有一篇文章改编了Javascript版本的计算,但它非常笨拙。我找到了一个优越的版本,因为:
- It also has an open license.
- 它还有一个开放许可证。
- It uses OOP principles.
- 它使用OOP原则。
- It has greater flexibility to choose the ellipsoid you want to use.
- 它具有更大的灵活性来选择您想要使用的椭球。
- It has more methods to allow for different calculations in the future.
- 它有更多的方法可以在将来进行不同的计算。
- It is well documented.
- 这是有据可查的。
VincentyDistanceCalculator
#9
1
This method would help you find the distance between to geographic location in km.
此方法可帮助您找到以km为单位的地理位置之间的距离。
private double getDist(double lat1, double lon1, double lat2, double lon2)
{
int R = 6373; // radius of the earth in kilometres
double lat1rad = Math.toRadians(lat1);
double lat2rad = Math.toRadians(lat2);
double deltaLat = Math.toRadians(lat2-lat1);
double deltaLon = Math.toRadians(lon2-lon1);
double a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
Math.cos(lat1rad) * Math.cos(lat2rad) *
Math.sin(deltaLon/2) * Math.sin(deltaLon/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
return d;
}
#10
0
I typically use MATLAB with the Mapping Toolbox, and then use the code in my Java using MATLAB Builder JA. It makes my life a lot simpler. Given most schools have it for free student access, you can try it out (or get the trial version to get over your work).
我通常将MATLAB与Mapping Toolbox一起使用,然后使用MATLAB Builder JA在我的Java中使用代码。它让我的生活变得更加简单。鉴于大多数学校都有免费学生访问权限,您可以尝试(或获得试用版来完成您的工作)。