获取地球两点之间的距离-DistanceUtil

This commit is contained in:
duandazhi
2021-04-05 00:01:24 +08:00
parent 1e003c016f
commit a37f17eef6
2 changed files with 93 additions and 0 deletions

View File

@@ -49,6 +49,7 @@ public class PatternPool {
public final static Pattern MONEY = Pattern.compile("^(\\d+(?:\\.\\d+)?)$");
/**
* 邮件符合RFC 5322规范正则来自http://emailregex.com/
* What is the maximum length of a valid email address? https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address/44317754
* 注意email 要宽松一点。比如 jetz.chong@hotmail.com、jetz-chong@ hotmail.com、jetz_chong@hotmail.com、dazhi.duan@com.cn 宽松一点把,都算是正常的邮箱
*/
public final static Pattern EMAIL = Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])", Pattern.CASE_INSENSITIVE);

View File

@@ -0,0 +1,92 @@
package cn.hutool.core.util;
import java.awt.geom.Point2D;
/**
* 通过经纬度获取地球上两点之间的距离
* @author dazer & neusoft
* @date 2021/4/4 23:42
* @since 5.6.3
* thank youJAVA通过经纬度获取两点之间的距离 https://www.cnblogs.com/pxblog/p/13359801.html
* thank youJAVA根据经纬度获取两点之间的距离 https://blog.csdn.net/weixin_35815479/article/details/106972772
* 百度地图拾取系统http://api.map.baidu.com/lbsapi/getpoint/index.html
* 高德地图拾取https://lbs.amap.com/tools/picker
*/
public class DistanceUtil {
/**地球半径单位KM*/
private static final double EARTH_RADIUS = 6378.137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 根据两个位置的经纬度来计算两地的距离单位为KM
* “经度”【longitude】、“纬度”【 Latitude】。
* 参数为String类型
* @param lat1Str 第一个位置经度
* @param lng1Str 第一个位置纬度
* @param lat2Str 第二个位置经度
* @param lng2Str 第二个位置纬度
* @return 地球上两点之间的距离单位KM
*/
public static String getDistance(String lat1Str, String lng1Str, String lat2Str, String lng2Str) {
double lat1 = 0;
double lng1 = 0;
double lat2 = 0;
double lng2 = 0;
try {
lat1 = Double.parseDouble(lat1Str);
lng1 = Double.parseDouble(lng1Str);
lat2 = Double.parseDouble(lat2Str);
lng2 = Double.parseDouble(lng2Str);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("经纬度入参不合法,请检查!", e);
}
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double difference = radLat1 - radLat2;
double mdifference = rad(lng1) - rad(lng2);
double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(difference / 2), 2)
+ Math.cos(radLat1) * Math.cos(radLat2)
* Math.pow(Math.sin(mdifference / 2), 2)));
distance = distance * EARTH_RADIUS;
distance = Math.round(distance * 10000) / 10000.0;
String distanceStr = distance+"";
distanceStr = distanceStr.
substring(0, distanceStr.indexOf("."));
return distanceStr;
}
/**
* 通过AB点经纬度获取距离 整数
* @param pointA A点(经,纬)
* @param pointB B点(经,纬)
* @return 距离(单位:米)
*/
public static long getDistance(Point2D pointA, Point2D pointB) {
// 经纬度角度转弧度。弧度用作参数以调用Math.cos和Math.sin
// A经弧度
double radiansAx = Math.toRadians(pointA.getX());
// A纬弧度
double radiansAy = Math.toRadians(pointA.getY());
// B经弧度
double radiansBx = Math.toRadians(pointB.getX());
// B纬弧度
double radiansBy = Math.toRadians(pointB.getY());
// 公式中“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);
// 反余弦值
double acos = Math.acos(cos);
// 最终结果
double h = EARTH_RADIUS * acos;
//四舍五入
//保留小数后两位
/** BigDecimal b = new BigDecimal(h);
double f1 = b.setScale(2, RoundingMode.HALF_UP).doubleValue();*/
return Math.round(h);
}
}