之前有两个项目都有巡查功能,基于电子围栏,获取两个点的距离是很常见的功能,用来统计当前用户到目标范围中心点大致距离,接受一定的误差,使用Haversine 公式 就能实现
java
import cn.hutool.core.util.NumberUtil;
public class LocationUtils {
private static double EARTH_RADIUS = 6378.137;
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 通过经纬度获取距离(单位:千米)
*
* @param lat1
* @param lng1
* @param lat2
* @param lng2
* @return
*/
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;
return NumberUtil.round(s, 2).doubleValue();
}
}
这是一个很常见的实现
下面给出其他语言版本
golangconst earthRadius = 6371 // 地球平均半径,单位:千米
// degToRad 将角度转换为弧度
func degToRad(deg float64) float64 {
return deg * math.Pi / 180
}
// GetDistance 计算两个经纬度之间的距离(单位:千米)
func GetDistance(lat1, lng1, lat2, lng2 float64) float64 {
radLat1 := degToRad(lat1)
radLat2 := degToRad(lat2)
a := radLat1 - radLat2
b := degToRad(lng1) - degToRad(lng2)
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 *= earthRadius
s = math.Round(s*100) / 100 // 保留两位小数
return s
}
Js版本
jsconst earthRadius = 6371; // 地球平均半径,单位:千米
function degToRad(deg) {
return deg * Math.PI / 180;
}
function getDistance(lat1, lng1, lat2, lng2) {
const radLat1 = degToRad(lat1);
const radLat2 = degToRad(lat2);
const a = radLat1 - radLat2;
const b = degToRad(lng1) - degToRad(lng2);
let 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 *= earthRadius;
s = Math.round(s * 100) / 100; // 保留两位小数
return s;
}
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!