坐标 转换

坐标分类

地图坐标分为几种:
1)国际坐标:GPS、WGS84又称为原始坐标,国际公认的世界标准坐标体系;
2)火星坐标:GCJ-02是国家测绘局在02年发布的坐标体系,在国内,至少得使用此坐标体系,比如:google、高德、腾讯地图等;
3)其他特殊坐标:一般都是由火星坐标通过偏移算法计算得出的,比如百度使用的是BD-09坐标,搜狗使用的是自己的搜狗坐标。

坐标转换原因

       国内目前的已知的地图所使用的坐标体系不同,这就造成有时候服务端给的坐标,在不同的地图上显示会存在很大的偏移差。因此需要进行坐标转换。

坐标转换方法

1、调用官方AP

如高德官方APII坐标转换:https://developer.amap.com/api/webservice/guide/api/convert

2、使用工具类

工具类转换有1-2米的误差,如需精确位置慎用

public static double pi = 3.1415926535897932384626;
    public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    public static double a = 6378245.0;
    public static double ee = 0.00669342162296594323;
	
    public static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    public static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }
    public static double[] transform(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return new double[]{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 double[]{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;
    }
    /**
     * WGS84转高德
     * 35.096775,111.045299
     */
    public static double[] gps84_To_Gcj02(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return new double[]{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 double[]{mgLat, mgLon};
    }
	/** 
     * 高德转84坐标 
     * */  
    public static double[] gcj02_To_Gps84(double lat, double lon) {  
        double[] gps = transform(lat, lon);  
        double lontitude = lon * 2 - gps[1];  
        double latitude = lat * 2 - gps[0];  
        return new double[]{latitude, lontitude};  
    }  
    /** 
     * 高德转百度坐标
     */  
    public static double[] gcj02_To_Bd09(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 tempLon = z * Math.cos(theta) + 0.0065;  
        double tempLat = z * Math.sin(theta) + 0.006;  
        double[] gps = {tempLat,tempLon};  
        return gps;  
    }  
  
    /** 
     * 百度转高德坐标
     */  
    public static double[] bd09_To_Gcj02(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 tempLon = z * Math.cos(theta);  
        double tempLat = z * Math.sin(theta);  
        double[] gps = {tempLat,tempLon};  
        return gps;  
    }  
  
    /**
     * 84转百度坐标
     */  
    public static double[] gps84_To_bd09(double lat,double lon){  
        double[] gcj02 = gps84_To_Gcj02(lat,lon);  
        double[] bd09 = gcj02_To_Bd09(gcj02[0],gcj02[1]);  
        return bd09;  
    }  

	/**
     * 百度转84坐标
     */  
    public static double[] bd09_To_gps84(double lat,double lon){  
        double[] gcj02 = bd09_To_Gcj02(lat, lon);  
        double[] gps84 = gcj02_To_Gps84(gcj02[0], gcj02[1]);  
        //保留小数点后六位  
        gps84[0] = retain6(gps84[0]);  
        gps84[1] = retain6(gps84[1]);  
        return gps84;  
    }  
  
    /*
     * 保留小数点后六位 
     */  
    private static double retain6(double num){  
        String result = String .format("%.6f", num);  
        return Double.valueOf(result);  
    }
}

本文参考:https://github.com/JackZhouCn/JZLocationConverter
感谢分享

你可能感兴趣的:(常识,坐标转换)