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;
}