1. 程式人生 > >Java、SQLServer 根據經緯度計算距離

Java、SQLServer 根據經緯度計算距離

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 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; } //計算兩個經緯度間的距離 public static double calculateDistance(Point point1, Point point2) { double radLat1 = rad(point1.getLatitude()); double radLat2 = rad(point2.getLatitude()); double a = radLat1 - radLat2; double b = rad(point1.getLongitude()) - rad(point2.getLongitude()); 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; } //校驗經緯度 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; private Point(String latitude, String longitude) { this.latitude = Double.valueOf(latitude); this.longitude = Double.valueOf(longitude); } private Point(double latitude, double longitude) { this.latitude = latitude; this.longitude = longitude; } public static Point build(String latitude, String longitude) { return new Point(latitude, longitude); } public static Point build(double latitude, double longitude) { return new Point(latitude, longitude); } public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } @Override public String toString() { return "latitude is -->"+latitude +" longitude is -->"+longitude; } } }

SQLServer

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
    --SET @Distance = Round(@Distance * 10000) / 10000  
    RETURN @Distance
  END

使用方法

dbo.fnGetDistance(%s,%s,latitude,longitude) as distance 

替換佔位符,第一個引數是緯度、第二個引數是經度