Introduction to common Coordinate systems

  • Wgs-84 (GPS) international standard, generally from the international standard GPS equipment to obtain coordinates are WGS-84, as well as the coordinate system used by international map providers.

  • Gcj-02 China standard, the coordinate system issued by national Survey bureau in 2002. Also known as “Mars coordinates”. In China, at least “GCJ-02” must be used to encrypt the location for the first time. For example, Google China, Autonavi, Tencent are using this coordinate system.

  • Bd-09 baidu standard, on the basis of “GCJ-02” for secondary encryption.

Beidou positioning System coordinates

If there are friends who have connected with the Beidou positioning system, they may find a problem. It seems that the latitude and longitude of the Beidou coordinates have been multiplied by 100.

A, $GNRMC, 083735.000, 2429.53531, N, E, 0.54, 171.11, 11810.78036, 190621, and A * 7 E

This is the coordinate value received by the Beidou Positioning system. It can be found that the north latitude is 2429.53531 and the east longitude is 11810.78036. If we divide the latitude and longitude by 100, 24.2953531 north latitude and 118.1078036 east longitude, and throw them into Baidu or AmAP, we will find that: The coordinates are out of line.

Amap positioning:

Baidu Map positioning:

Can find that both are offset a few tens of kilometers distances, the reason is that domestic, either gold or baidu, the latitude and longitude values, they use value after are encrypted, rather than the actual latitude and longitude using GPS to locate, therefore, if we want to coordinate system of beidou positioning system, used for commercial map, Then it needs to go through the corresponding encryption conversion process to be able to use correctly.

The transformation of coordinates

First of all, it should be emphasized that in fact, the coordinate system value of our Beidou positioning is not a simple 100-fold relationship, but a degree, minute and second conversion is required. Therefore, the beidou coordinate values obtained by us are 2429.53531 NORTH latitude and 11810.78036 east longitude, which need to be calculated as follows: 24+ (29.53531/60) ≈ 24.49225517 118+ (10.78036/60) ≈118.17967267

These two values are the coordinate values that we should put into the transformation formula. If we directly use the value of 100 times the relation to transform, the positioning will also be biased

I’m gonna go ahead and do the code

  public static final String BAIDU_LBS_TYPE = "bd09ll";
    public static double pi = 3.1415926535897932384626;
    public static double a = 6378245.0;
    public static double ee = 0.00669342162296594323;

    /** * Calculate the beidou coordinate system degree in seconds *@param msg
     * @return* /
    public static GPS str_To_Gps84(String msg){
        double lat = 0;
        double lon = 0;
        String[] split = msg.split(",");
        if (split[4].equals("N") || split[4].equals("S")) {int i = split[3].indexOf(".");
            String latInt = split[3].substring(0, i - 2);
            String latDec = split[3].substring(i-2);
            int i1 = split[5].indexOf(".");
            String lonInt = split[5].substring(0, i1-2);
            String lonDec = split[5].substring(i1-2);
            lat = Integer.parseInt(latInt) + Double.parseDouble(latDec)/60;
            lon = Integer.parseInt(lonInt) + Double.parseDouble(lonDec)/60;
            System.out.println("latInt = "+ latInt);
            System.out.println("latDec = "+ latDec);
            System.out.println("lonInt = "+ lonInt);
            System.out.println("lonDec = "+ lonDec);
            System.out.println("lat = "+ lat);
            System.out.println("lon = "+ lon);
        } else {
            return null;
        }

        return new GPS(lat,lon);
    }




    /** * 84 to Mars coordinate system (gcj-02) *@param lat
     * @param lon
     */
    public static GPS gps84_To_Gcj02(double lat, double lon) {
        if (outOfChina(lat, lon))
        {
            return null;
        }
        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);
    }

    /** ** Mars coordinate system (GCJ-02) to 84 **@param lon * @param lat * @return* /
    public static GPS gcj_To_Gps84(double lat, double lon) {
        GPS gps = transform(lat, lon);
        double lontitude = lon * 2 - gps.getLon();
        double latitude = lat * 2 - gps.getLat();
        return new GPS(latitude, lontitude);
    }

    /** * convert gcj-02 to bD-09 **@param gg_lat
     * @param gg_lon
     */
    public static GPS gcj02_To_Bd09(double gg_lat, double gg_lon) {
        double x = gg_lon, y = gg_lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new GPS(bd_lat, bd_lon);
    }

    /** ** convert bD-09 to gcj-02 ** *@param
     * bd_lat * @param bd_lon * @return* /
    public static GPS bd09_To_Gcj02(double bd_lat, double bd_lon) {
        double x = bd_lon - 0.0065;
        double y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new GPS(gg_lat, gg_lon);
    }

    /**
     * (BD-09)-->84
     * @param bd_lat
     * @param bd_lon
     * @return* /
    public static GPS bd09_To_Gps84(double bd_lat, double bd_lon) {

        GPS gcj02 = bd09_To_Gcj02(bd_lat, bd_lon);
        GPS map84 = gcj_To_Gps84(gcj02.getLat(),
                gcj02.getLon());
        return map84;

    }

    /**
     * is or not outOfChina
     * @param lat
     * @param lon
     * @return* /
    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;
    }

    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 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;
    }
// Find the distance between two coordinates
    public static double distance(double lonA,double latA,double lonB,double latB){
        int earthR = 6371000;
        double x = Math.cos(latA * PI / 180.) * Math.cos(latB * PI / 180.) * Math.cos((lonA - lonB) * PI / 180);
        double y = Math.sin(latA * PI / 180.) * Math.sin(latB * PI / 180.);
        double s = x + y;
        if (s > 1) s = 1;
        if (s < -1) s = -1;
        double alpha = Math.acos(s);
        double distance = alpha * earthR;
        return distance;
    }
    // Reload, calculate the distance according to two points
    public static double distance(GPS p1,GPS p2){
        return distance(p1.getLon(), p1.getLat(), p2.getLon(), p2.getLat());
    }
Copy the code

Transformation results of GCJ-02 coordinate system for AmAP

public CommonResult test(a) {
        String msg = A, "$GNRMC, 083735.000, 2429.53531, N, 11810.78036 E, 0.54, 171.11, 190621,,, A * 7 E";

        GPS gps2 = GPSConverterUtils.str_To_Gps84(msg);

        GPS gps = GPSConverterUtils.gps84_To_Gcj02(gps2.getLat(), gps2.getLon());
        return CommonResult.success(gps);
    }
Copy the code
"Lat" : 24.489503175446604, "says lon" : 118.18449589009587Copy the code

You can see that the coordinate system is converted to our office building

The transformation result of BD-09 coordinate system of Baidu coordinate system:

    
public CommonResult test(a) {
        String msg = A, "$GNRMC, 083735.000, 2429.53531, N, 11810.78036 E, 0.54, 171.11, 190621,,, A * 7 E";
    GPS gps2 = GPSConverterUtils.str_To_Gps84(msg);

    GPS gps = GPSConverterUtils.gps84_To_Gcj02(gps2.getLat(), gps2.getLon());
     GPS gps1 = GPSConverterUtils.gcj02_To_Bd09(gps.getLat(), gps.getLon());
    return CommonResult.success(gps1);
}
Copy the code
"Lat" : 24.49580387761381, "says lon" : 118.19095399371493Copy the code

You can see that the Baidu map also accurately locates our office building

conclusion

Google maps, with the WGS-84 coordinate system, the beidou positioning system to the coordinate value to do a degree, minutes and seconds of conversion, after the conversion is 84 coordinates, like Amap those with gCJ-02 Mars coordinate system, equals to do a GCJ-02 encryption, coordinate system can be used in AmAP, Baidu maps need to do a BD-09 encryption