参考:经纬度计算_onway_goahead的博客-优快云博客_经纬度计算开发经常会遇到经纬度计算的相关场景。这次对相关知识做了下整理。首先回顾一下科普知识:1,经度: 英文 longitude 缩写 lng;纬度:英文 latitude 缩写 lat。2,经度 是地球上一个地点离一根被称为本初子午线的南北方向走线以东或以西的度数。本初子午线的经度是0°。纬度 是指某点与地球球心的连线和地球赤道面所成的线面角。3,角度的是60进制的,在程序...
https://blog.youkuaiyun.com/onway_goahead/article/details/105460737
方法一:
/**
* 方法一:
*/
private const double EARTH_RADIUS = 6377.830;//地球半径(千米)
/// <summary>
/// 角度换算成弧度
/// </summary>
/// <param name="d">角度</param>
/// <returns>弧度</returns>
private static double rad(double d)
{
return d * Math.PI / 180.0;
}
/// <summary>
/// 计算距离
/// </summary>
/// <param name="lat1">纬度1</param>
/// <param name="lng1">经度1</param>
/// <param name="lat2">纬度2</param>
/// <param name="lng2">经度2</param>
/// <returns>距离(千米)</returns>
public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double radLng1 = rad(lng1);
double radLng2 = rad(lng2);
double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
/**
* 方法二:
*/
/// <summary>
/// 计算距离
/// </summary>
/// <param name="lat1">纬度1</param>
/// <param name="lng1">经度1</param>
/// <param name="lat2">纬度2</param>
/// <param name="lng2">经度2</param>
/// <returns>距离(千米)</returns>
public static double GetDistance2(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
方法二:
/// <summary>
/// 根据距离计算某点角度偏差
/// </summary>
/// <param name="lat">纬度</param>
/// <param name="distance">距离(千米)</param>
/// <param name="latDeviation">纬度偏差</param>
/// <param name="lngDeviation">经度偏差</param>
public static void GetMaxDeviation(double lat, double distance, out double latDeviation, out double lngDeviation)
{
double radLat1 = rad(lat);
//另一种根据纬度计算地球半径的写法,因为极地半径和赤道半径有偏差。
//EARTH_RADIUS = 6356.9088 + 20.9212 * (90.0 - lat) / 90.0;
double latRatio = 180 / (Math.PI * EARTH_RADIUS); //经线上1公里对应纬度偏差
double lngRatio = latRatio / Math.Cos(radLat1);//纬线上1公里对应经度偏差
latDeviation = distance * latRatio;
lngDeviation = distance * lngRatio;
}
方法三:
// 分析 https://blog.youkuaiyun.com/jk940438163/article/details/83147557#commentsedit
package com.zhiliyuchi.web.rest.util;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: TODO
*/
public class Test {
private static final double EARTH_RADIUS = 6371393; // 平均半径,单位:m;不是赤道半径。赤道为6378左右
/**
* @描述 反余弦进行计算
* @参数 [lat1, lng1, lat2, lng2]
* @返回值 double
* @创建人 Young
* @创建时间 2019/3/13 20:31
**/
public static double getDistance(Double lat1,Double lng1,Double lat2,Double lng2) {
// 经纬度(角度)转弧度。弧度用作参数,以调用Math.cos和Math.sin
double radiansAX = Math.toRadians(lng1); // A经弧度
double radiansAY = Math.toRadians(lat1); // A纬弧度
double radiansBX = Math.toRadians(lng2); // B经弧度
double radiansBY = Math.toRadians(lat2); // B纬弧度
// 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
+ Math.sin(radiansAY) * Math.sin(radiansBY);
// System.out.println("cos = " + cos); // 值域[-1,1]
double acos = Math.acos(cos); // 反余弦值
// System.out.println("acos = " + acos); // 值域[0,π]
// System.out.println("∠AOB = " + Math.toDegrees(acos)); // 球心角 值域[0,180]
return EARTH_RADIUS * acos; // 最终结果
}
public static void main(String[] args) {
//121.717594,31.12055 121.817629,31.090867
double distance = getDistance(31.12055, 121.717594,
31.090867, 121.817629);
System.out.println("距离" + distance + "米");
}
}
方法四:
package com.zhiliyuchi.web.rest.util;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: 高德地图对应经纬度计算距离
*/
public class LocationUtils {
// 地球赤道半径
private static double EARTH_RADIUS = 6378.137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* @描述 经纬度获取距离,单位为米
* @参数 [lat1, lng1, lat2, lng2]
* @返回值 double
* @创建人 Young
* @创建时间 2019/3/13 20:33
**/
public static double getDistance(double lat1, double lng1, double lat2,
double lng2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+ Math.cos(radLat1) * Math.cos(radLat2)
* Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.round(s * 10000d) / 10000d;
s = s * 1000;
return s;
}
public static void main(String[] args) {
double distance = getDistance(31.12055, 131.717594,
21.090867, 111.817629);
System.out.println("距离" + distance + "米");
}
}
方法五:
// maven 依赖
<dependency>
<groupId>org.gavaghan</groupId>
<artifactId>geodesy</artifactId>
<version>1.1.3</version>
</dependency>
// ==================================================================
package com.zhiliyuchi.web.rest.util;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
/**
* @创建人:Young
* @时 间: 2019/3/13
* @描 述: TODO
*/
public class test0 {
public static void main(String[] args)
{
// //121.717594,31.12055 121.817629,31.090867
GlobalCoordinates source = new GlobalCoordinates(31.12055, 121.717594);
GlobalCoordinates target = new GlobalCoordinates(31.090867, 121.817629);
double meter1 = getDistanceMeter(source, target, Ellipsoid.Sphere);
double meter2 = getDistanceMeter(source, target, Ellipsoid.WGS84);
System.out.println("Sphere坐标系计算结果:"+meter1 + "米");
System.out.println("WGS84坐标系计算结果:"+meter2 + "米");
}
public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid)
{
//创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
return geoCurve.getEllipsoidalDistance();
}
}