JAVA utm转wgs84坐标 互转

727 阅读5分钟

package com.zhidao.ochmanager.utils;

import com.zhidao.ochmanager.dto.LocationDTO;

import java.math.BigDecimal;

public class UtmWgs84LonLatConvert {

    /* Ellipsoid model constants (actual values here are for WGS84) */
    private final static double K0 = 0.9996;

    private final static double E = 0.00669438;
    private final static double E2 = E * E;
    private final static double E3 = E2 * E;
    private final static double E_P2 = E / (1.0 - E);

    private final static double SQRT_E = Math.sqrt(1 - E);
    private final static double _E = (1 - SQRT_E) / (1 + SQRT_E);
    private final static double _E2 = _E * _E;
    private final static double _E3 = _E2 * _E;
    private final static double _E4 = _E3 * _E;
    private final static double _E5 = _E4 * _E;

    private final static double M1 = (1 - E / 4 - 3 * E2 / 64 - 5 * E3 / 256);
    private final static double M2 = (3 * E / 8 + 3 * E2 / 32 + 45 * E3 / 1024);
    private final static double M3 = (15 * E2 / 256 + 45 * E3 / 1024);
    private final static double M4 = (35 * E3 / 3072);

    private final static double P2 = (3. / 2 * _E - 27. / 32 * _E3 + 269. / 512 * _E5);
    private final static double P3 = (21. / 16 * _E2 - 55. / 32 * _E4);
    private final static double P4 = (151. / 96 * _E3 - 417. / 128 * _E5);
    private final static double P5 = (1097. / 512 * _E4);

    private final  static Integer R = 6378137;

    public static LocationDTO UtmToLatLon(double easting, double northing, int zone_number) {


        double x = easting - 500000;
        double y = northing;
        double m = y / K0;
        double mu = m / (R * M1);

        double p_rad = (mu +
                P2 * Math.sin(2 * mu) +
                P3 * Math.sin(4 * mu) +
                P4 * Math.sin(6 * mu) +
                P5 * Math.sin(8 * mu));

        double p_sin = Math.sin(p_rad);
        double p_sin2 = p_sin * p_sin;

        double p_cos = Math.cos(p_rad);

        double p_tan = p_sin / p_cos;
        double p_tan2 = p_tan * p_tan;
        double p_tan4 = p_tan2 * p_tan2;

        double ep_sin = 1 - E * p_sin2;
        double ep_sin_sqrt = Math.sqrt(1 - E * p_sin2);

        double n = R / ep_sin_sqrt;
        double r = (1 - E) / ep_sin;

        double c = E_P2 * (p_cos * p_cos);
        double c2 = c * c;

        double d = x / (n * K0);
        double d2 = d * d;
        double d3 = d2 * d;
        double d4 = d3 * d;
        double d5 = d4 * d;
        double d6 = d5 * d;

        double latitude = (p_rad - (p_tan / r) *
                (d2 / 2 - d4 / 24 * (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
                d6 / 720 * (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2));
        double longitude = (d - d3 / 6 * (1 + 2 * p_tan2 + c) + d5 / 120 * (5 - 2 * c + 28 * p_tan2 - 3 * c2 + 8 * E_P2 + 24 * p_tan4)) / p_cos;
        longitude = modAngle(longitude + Math.toRadians(zoneNumberToCentralLongitude(zone_number)));
        return LocationDTO.builder().lon(BigDecimal.valueOf(Math.toDegrees(longitude))).lat(BigDecimal.valueOf(Math.toDegrees(latitude))).build();
    }

    public static void main(String[] args) {
    
    
        LocationDTO locationDTO1 = UtmWgs84LonLatConvert.UtmToLatLon(448678.0057576791, 4426019.733020873, 50);
        System.out.println(locationDTO1.getLon());
        System.out.println(locationDTO1.getLat());
    }

    private static int zoneNumberToCentralLongitude(int zone_number) {
        return (zone_number - 1) * 6 - 180 + 3;
    }

    private static double modAngle(double value) {
        return (value + Math.PI) % (2 * Math.PI) - Math.PI;
    }


}

// 使用开始站点坐标的经度计算时区zone

int zone = (int) Math.round((183 + cs.getWgs84Lon().doubleValue()) / 6);

    private LocationDTO processLocation(String lineStr, int zone) {
        String[] split = lineStr.split(",", 3);
        try {
            LocationDTO locationDTO = UtmWgs84LonLatConvert.UtmToLatLon(Double.valueOf(split[0]), Double.valueOf(split[1]), zone);
            return locationDTO;
        } catch (Exception e) {
            log.error("split0:{},split1:{}", split[0], split[1]);
//            e.printStackTrace();
        }
        return null;
    }