一 : 反余弦計(jì)算方式
1.1 : 工具類
無需依賴外部jar,可直接計(jì)算距離。DistanceUtil.java
package com.utils;
import java.math.BigDecimal;
public class DistanceUtil {
//平均半徑,單位:m;不是赤道半徑。赤道為6378左右
private static final double EARTH_RADIUS = 6371000;
public static BigDecimal getDistanceBigDecimalOneDecimalPlace(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2) {
return getDistanceBigDecimal(lat1, lng1, lat2, lng2).setScale(1, BigDecimal.ROUND_HALF_UP);
}
public static BigDecimal getDistanceBigDecimal(BigDecimal lat1, BigDecimal lng1, BigDecimal lat2, BigDecimal lng2) {
//經(jīng)緯度(角度)轉(zhuǎn)弧度?;《扔米鲄?shù),以調(diào)用Math.cos和Math.sin
BigDecimal radiansAX = new BigDecimal(Math.toRadians(lng1.doubleValue()));//A經(jīng)弧度
BigDecimal radiansAY = new BigDecimal(Math.toRadians(lat1.doubleValue()));//A緯弧度
BigDecimal radiansBX = new BigDecimal(Math.toRadians(lng2.doubleValue()));//B經(jīng)弧度
BigDecimal radiansBY = new BigDecimal(Math.toRadians(lat2.doubleValue()));//B緯弧度
//公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
BigDecimal cos = new BigDecimal(Math.cos(radiansAY.doubleValue()) * Math.cos(radiansBY.doubleValue()) * Math.cos(radiansAX.doubleValue() - radiansBX.doubleValue())
+ Math.sin(radiansAY.doubleValue()) * Math.sin(radiansBY.doubleValue()));
// log.info("cos = " + cos);//值域[-1,1]
BigDecimal acos = new BigDecimal(Math.acos(cos.doubleValue()));//反余弦值
// log.info("acos = " + acos);//值域[0,π]
// log.info("∠AOB = " + Math.toDegrees(acos));//球心角 值域[0,180]
return new BigDecimal(EARTH_RADIUS).multiply(acos);//最終結(jié)果
}
public static double getDistanceDouble(Double lat1, Double lng1, Double lat2, Double lng2) {
//經(jīng)緯度(角度)轉(zhuǎn)弧度?;《扔米鲄?shù),以調(diào)用Math.cos和Math.sin
double radiansAX = Math.toRadians(lng1);//A經(jīng)弧度
double radiansAY = Math.toRadians(lat1);//A緯弧度
double radiansBX = Math.toRadians(lng2);//B經(jīng)弧度
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);
// log.info("cos = " + cos);//值域[-1,1]
double acos = Math.acos(cos);//反余弦值
// log.info("acos = " + acos);//值域[0,π]
// log.info("∠AOB = " + Math.toDegrees(acos));//球心角 值域[0,180]
return EARTH_RADIUS * acos;//最終結(jié)果
}
public static void main(String[] args) {
System.out.println("距離" + getDistanceDouble(31.22814, 121.400136,31.229016, 121.398455) + "米");
System.out.println("距離" + getDistanceBigDecimal(new BigDecimal("31.22814"), new BigDecimal("121.400136"),
new BigDecimal("31.229016"), new BigDecimal("121.398455")) + "米");
System.out.println("距離" + getDistanceBigDecimalOneDecimalPlace(new BigDecimal("31.22814"), new BigDecimal("121.400136"),
new BigDecimal("31.229016"), new BigDecimal("121.398455")) + "米");
}
}
1.2 : 驗(yàn)證
可根據(jù)精度來判斷使用哪種方式(BigDecimal,double)。
在使用時(shí)具體保留位數(shù)可自行設(shè)置。
二 : 利用第三方j(luò)ar
2.1 : 添加依賴
添加第三方j(luò)ar包。
<!-- 計(jì)算兩經(jīng)緯度之間的距離 -->
<dependency>
<groupId>org.gavaghan</groupId>
<artifactId>geodesy</artifactId>
<version>1.1.3</version>
</dependency>
2.2 : 工具類
直接采用第三方j(luò)ar包中的工具進(jìn)行計(jì)算。DistanceUtil.java
package com.utils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import java.math.BigDecimal;
public class DistanceUtil {
public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) {
//創(chuàng)建GeodeticCalculator,調(diào)用計(jì)算方法,傳入坐標(biāo)系、經(jīng)緯度用于計(jì)算距離
GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
return geoCurve.getEllipsoidalDistance();
}
public static void main(String[] args) {
GlobalCoordinates source = new GlobalCoordinates(31.22814, 121.400136);
GlobalCoordinates target = new GlobalCoordinates(31.229016, 121.398455);
double meter1 = getDistanceMeter(source, target, Ellipsoid.Sphere);
double meter2 = getDistanceMeter(source, target, Ellipsoid.WGS84);
System.out.println("Sphere坐標(biāo)系計(jì)算結(jié)果:" + meter1 + "米");
System.out.println("WGS84 坐標(biāo)系計(jì)算結(jié)果:" + meter2 + "米");
}
}
2.3 : 驗(yàn)證
三 : 總結(jié)
將其結(jié)果放在一起對(duì)比,會(huì)發(fā)現(xiàn)第三方j(luò)ar,Sphere更精準(zhǔn)一些。
如果不想引入jar,建議直接采用:反余弦計(jì)算方式。文章來源:http://www.zghlxwxcb.cn/news/detail-623884.html
參考:https://blog.51cto.com/zhangxueliang/2969393文章來源地址http://www.zghlxwxcb.cn/news/detail-623884.html
到了這里,關(guān)于JAVA計(jì)算兩經(jīng)緯度間的距離的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!