在开发过程中,我们经常需要计算两个地理位置之间的距离。本文将介绍如何在Java和SQL Server、MySQL中实现经纬度距离的计算。
Java 实现
经纬度校验
首先,我们需要校验输入的经纬度是否合法。这里使用正则表达式来校验:
public class DistanceUtils {
// 经度校验正则表达式
private static final String longitudePattern = "^[\\-\\+]?0(\\.\\d{0,7}){0,1}|(0?\\d{1,2}\\.\\d{0,7}|1[0-7]?\\d\\.\\d{0,7}|180\\.0{0,7})$";
// 纬度校验正则表达式
private static final String latitudePattern = "^[\\-\\+]?0(\\.\\d{0,7}){0,1}|([0-8]?\\d{1}\\.\\d{0,7}|90\\.0{0,7})$";
// 地球半径
private static final double EARTH_RADIUS = 6378137;
// 计算弧度
private static double rad(double d) {
return d * Math.PI / 180.0;
}
// 校验经纬度
public static void valid(String latitude, String longitude) {
if (Strings.isNullOrEmpty(latitude) || Strings.isNullOrEmpty(longitude)) {
throw new Exception("经纬度不能为空");
}
if (!longitude.matches(longitudePattern)) {
throw new Exception("经度不合法");
}
if (!latitude.matches(latitudePattern)) {
throw new Exception("纬度不合法");
}
}
// 用于封装经纬度
public static class Point {
private double latitude;
private double longitude;
// 构造函数和方法省略...
}
}
距离计算
接下来,我们实现计算两个经纬度间距离的方法:
public class DistanceUtils {
// 计算两个经纬度间的距离
public static double calculateDistance(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;
}
// 计算两个经纬度间的距离(使用Point类)
public static double calculateDistance(Point point1, Point point2) {
// 方法实现与上面相同,使用Point对象的经纬度
}
}
SQL Server 实现
在SQL Server中,我们可以通过创建一个函数来实现距离计算:
CREATE FUNCTION [dbo].[fnGetDistance](@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) RETURNS FLOAT
AS
BEGIN
-- 距离(千米)
DECLARE @Distance REAL
DECLARE @EARTH_RADIUS REAL
SET @EARTH_RADIUS = 6378.137
DECLARE @RadLatBegin REAL, @RadLatEnd REAL, @RadLatDiff REAL, @RadLngDiff REAL
SET @RadLatBegin = @LatBegin * PI() / 180.0
SET @RadLatEnd = @LatEnd * PI() / 180.0
SET @RadLatDiff = @RadLatBegin - @RadLatEnd
SET @RadLngDiff = @LngBegin * PI() / 180.0 - @LngEnd * PI() / 180.0
SET @Distance = 2 * ASIN(SQRT(POWER(SIN(@RadLatDiff / 2), 2) + COS(@RadLatBegin) * COS(@RadLatEnd) * POWER(SIN(@RadLngDiff / 2), 2)))
SET @Distance = @Distance * @EARTH_RADIUS
RETURN @Distance
END
使用方法
在SQL查询中,你可以这样使用这个函数:
SELECT dbo.fnGetDistance(%s, %s, latitude, longitude) as distance
替换占位符%s
为实际的纬度和经度值。
基于提供的搜索结果,我们可以在MySQL中实现经纬度距离计算。以下是MySQL实现的详细步骤和代码示例:
MySQL 经纬度距离计算
使用 ST_Distance_Sphere
函数
MySQL 5.7及以上版本提供了 ST_Distance_Sphere
函数,可以方便地计算两点间的距离(单位:米)。
使用 ST_Distance_Sphere
函数计算距离:
SELECT id,
ST_Distance_Sphere(POINT(longitude, latitude), POINT(118.8800050, 31.9396860)) AS distance
FROM scenic
ORDER BY distance ASC;