Java、SQLServer 根据经纬度计算距离

来源:互联网 发布:lol韩服数据库 编辑:程序博客网 时间:2024/05/28 05:18

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 FLOATAS  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 

替换占位符,第一个参数是纬度、第二个参数是经度

0 0
原创粉丝点击