java中的坐标转换及测距

本文介绍了一个坐标转换工具类,包括WGS-84、BD-09及GCJ-02坐标系之间的相互转换方法,并提供了计算两点间直线距离的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 坐标转换类
 */
public class PositionUtil
{
    static double pi = 3.14159265358979324;// 圆周率
    static double a = 6378245.0;//卫星椭球坐标投影到平面地图坐标系的投影因子
    static double ee = 0.00669342162296594323;//椭球的偏心率
    public final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;//圆周率转换量
   
    //WGS-84坐标:是国际标准,GPS坐标
    //BD-09坐标:百度坐标偏移标准,Baidu Map使用
    //GCJ-02坐标:中国坐标偏移标准,Google Map、高德、腾讯使用
   
    /**
     * WGS-84坐标转换为BD-09坐标
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return BD-09坐标
     */
    public static double[] wgs2bd(double lat, double lon)
    {
        double[] wgs2gcj = wgs2gcj(lat, lon);
        double[] gcj2bd = gcj2bd(wgs2gcj[0], wgs2gcj[1]);
        return gcj2bd;
    }
   
    /**
     * BD-09坐标转换为WGS-84坐标
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return WGS-84坐标
     */
    public static double[] bd2wgs(double lat, double lon)
    {
        double[] bd2gcj = bd2gcj(lat, lon);
        double[] bd2wgs = gcj2wgs(bd2gcj[0], bd2gcj[1]);
        return bd2wgs;
    }

   
    /**
     * BD-09坐标转换为GCJ-02坐标
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return GCJ-02坐标
     */
    public static double[] bd2gcj(double lat, double lon)
    {
        double x = lon - 0.0065, y = lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new double[] {gg_lat, gg_lon};
    }

    /**
     * GCJ-02坐标转换为BD-09坐标。
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return  BD-09坐标
     */
    public static double[] gcj2bd(double lat, double lon)
    {
        double x = lon, y = lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new double[] {bd_lat, bd_lon};
    }
   
    /**
     * WGS-84坐标转换为GCJ-02坐标
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return GCJ-02坐标
     */
    public static double[] wgs2gcj(double lat, double lon)
    {
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ( (a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        double[] loc = {mgLat, mgLon};
        return loc;
    }

    /**
     * GCJ-02坐标转换为WGS-84坐标
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return WGS-84坐标
     */
    public static double[] gcj2wgs(double lat, double lon)
    {
        Gps gps = transform(lat, lon); 
        double lontitude = lon * 2 - gps.getWgLon(); 
        double latitude = lat * 2 - gps.getWgLat(); 
        return new double[]{latitude, lontitude}; 
    }

   
    /**
     * 转换纬度
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return lat 转后纬度
     */
    private static double transformLat(double lat, double lon)
    {
        double ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1
                     * lat * lon + 0.2 * Math.sqrt(Math.abs(lat));
        ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat
                                                                  * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lon * pi) + 40.0 * Math.sin(lon / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lon / 12.0 * pi) + 320 * Math.sin(lon * pi
                                                                   / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    /**
     * 转换经度
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return lon 转后经度
     */
    private static double transformLon(double lat, double lon)
    {
        double ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat
                     * lon + 0.1 * Math.sqrt(Math.abs(lat));
        ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat
                                                                  * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lat / 12.0 * pi) + 300.0 * Math.sin(lat / 30.0
                                                                     * pi)) * 2.0 / 3.0;
        return ret;
    }
   
    /**
     * 经纬度转换
     * @param lat 转前纬度
     * @param lon 转前经度
     * @return GPS
     */
    public static Gps transform(double lat, double lon) { 
        if (outOfChina(lat, lon)) { 
            return new Gps(lat, lon); 
        } 
        double dLat = transformLat(lon - 105.0, lat - 35.0); 
        double dLon = transformLon(lon - 105.0, lat - 35.0); 
        double radLat = lat / 180.0 * pi; 
        double magic = Math.sin(radLat); 
        magic = 1 - ee * magic * magic; 
        double sqrtMagic = Math.sqrt(magic); 
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); 
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); 
        double mgLat = lat + dLat; 
        double mgLon = lon + dLon; 
        return new Gps(mgLat, mgLon); 
    } 
   
    public static boolean outOfChina(double lat, double lon) {
               if (lon < 72.004 || lon > 137.8347)
                     return true;
                 if (lat < 0.8293 || lat > 55.8271)
                    return true;
                return false;
           }
    

  /**
     * 获取当前坐标和目的地之间的直线距离,单位KM
     * @param curLng 当前经度
     * @param curLat 当前纬度
     * @param destLng 目标经度
     * @param DestLat 目标纬度
     * @return
     */
    public static String getDistance(String curLng,String curLat,String destLng,String DestLat)
    {
     Double lat1 = Double.parseDouble(curLat);
        Double lng1 = Double.parseDouble(curLng);
        Double lat2 = Double.parseDouble(DestLat);
        Double lng2 = Double.parseDouble(destLng);
         
        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;
        String distanceStr = distance+"";
        distanceStr = distanceStr.
            substring(0, distanceStr.indexOf("."));
         
        return distanceStr;
    }


}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值