Java - 坐标转换工具类 WGS84 ⇋ GCJ02

原JS代码

double计算小数点后7位后有误差

public class CoordinateUtils {

    private static final int a = 6378245;
    private static final double ee = 0.006693421622965823;
    private static final double PI = Math.PI;

    private static double sin(double d) {
        return Math.sin(d);
    }

    private static double cos(double d) {
        return Math.cos(d);
    }

    private static double sqrt(double d) {
        return Math.sqrt(d);
    }

    private static double abs(double d) {
        return Math.abs(d);
    }

    private static boolean isInChinaBox(double lon, double lat) {
        return lon >= 72.004 && lon <= 137.8347 && lat >= 0.8293 && lat <= 55.8271;
    }

    private static double transformLat(double x, double y) {
        double ret = -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x));
        ret += (20 * sin(6 * x * PI) + 20 * sin(2 * x * PI)) * 2 / 3;
        ret += (20 * sin(y * PI) + 40 * sin(y / 3 * PI)) * 2 / 3;
        ret += (160 * sin(y / 12 * PI) + 320 * sin(y * PI / 30)) * 2 / 3;
        return ret;
    }

    private static double transformLon(double x, double y) {
        double ret = 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
        ret += (20 * sin(6 * x * PI) + 20 * sin(2 * x * PI)) * 2 / 3;
        ret += (20 * sin(x * PI) + 40 * sin(x / 3 * PI)) * 2 / 3;
        ret += (150 * sin(x / 12 * PI) + 300 * sin(x / 30 * PI)) * 2 / 3;
        return ret;
    }

    private static CoordinateObj delta(double lon, double lat) {
        double dLon = transformLon(lon - 105, lat - 35);
        double dLat = transformLat(lon - 105, lat - 35);
        double radLat = lat / 180 * PI;
        double magic = sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = sqrt(magic);
        dLon = (dLon * 180) / (a / sqrtMagic * cos(radLat) * PI);
        dLat = (dLat * 180) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
        return new CoordinateObj(dLon, dLat);
    }

    public static CoordinateObj WGS84ToGCJ02(double lon, double lat) {
        CoordinateObj coordinate = new CoordinateObj(lon, lat);
        if (!isInChinaBox(lon, lat)) {
            System.out.println(">>> WGS84ToGCJ02 当前坐标不在中国:" + coordinate.toString());
            return coordinate;
        }
        CoordinateObj d = delta(lon, lat);
        return new CoordinateObj(lon + d.getLon(), lat + d.getLat());
    }

    public static CoordinateObj GCJ02ToWGS84(double lon, double lat) {
        CoordinateObj coordinate = new CoordinateObj(lon, lat);
        if (!isInChinaBox(lon, lat)) {
            System.out.println(">>> GCJ02ToWGS84 当前坐标不在中国:" + coordinate.toString());
            return coordinate;
        }
        CoordinateObj wgs = new CoordinateObj(lon, lat);
        CoordinateObj tempPoint = WGS84ToGCJ02(wgs.getLon(), wgs.getLat());
        double dx = tempPoint.getLon() - lon;
        double dy = tempPoint.getLat() - lat;
        double wgsLon = wgs.getLon();
        double wgsLat = wgs.getLat();
        while (abs(dx) > 1e-6 || abs(dy) > 1e-6) {
            wgsLon -= dx;
            wgsLat -= dy;
            tempPoint = WGS84ToGCJ02(wgsLon, wgsLat);
            dx = tempPoint.getLon() - lon;
            dy = tempPoint.getLat() - lat;
        }
        return new CoordinateObj(wgsLon, wgsLat);
    }

    public static void main(String[] args) {
        double lon = 135.5776;
        double lat = 48.9981;

        CoordinateObj gcj = WGS84ToGCJ02(lon, lat);
        System.out.println(">>> gcj = " + gcj);
        CoordinateObj wgs = GCJ02ToWGS84(gcj.getLon(), gcj.getLat());
        System.out.println(">>> wgs = " + wgs);
        CoordinateObj gcj2 = WGS84ToGCJ02(wgs.getLon(), wgs.getLat());
        System.out.println(">>> gcj = " + gcj2);
        CoordinateObj wgs2 = GCJ02ToWGS84(gcj2.getLon(), gcj2.getLat());
        System.out.println(">>> wgs = " + wgs2);
    }
    
}

class CoordinateObj {

    private double lon;
    private double lat;

    public CoordinateObj() {
    }

    public CoordinateObj(double lon, double lat) {
        this.lon = lon;
        this.lat = lat;
    }

    @Override
    public String toString() {
        return "CoordinateObj{" +
                "lon=" + lon +
                ", lat=" + lat +
                '}';
    }

    public double getLon() {
        return lon;
    }

    public void setLon(double lon) {
        this.lon = lon;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值