| | |
| | | private static final DecimalFormat COORDINATE_FORMAT = new DecimalFormat("0.0000000"); |
| | | |
| | | /** |
| | | * 将局部坐标转换为经纬度坐标 |
| | | * 将局部坐标转换为经纬度坐标 |
| | | * |
| | | * @param localX 局部X坐标(厘米) |
| | | * @param localY 局部Y坐标(厘米) |
| | | * @param latA 点A的纬度(度分格式) |
| | | * @param lonA 点A的经度(度分格式) |
| | | * @param latB 点B的纬度(度分格式) |
| | | * @param lonB 点B的经度(度分格式) |
| | | * @param localXA 点A的局部X坐标(厘米) |
| | | * @param localYA 点A的局部Y坐标(厘米) |
| | | * @param localXB 点B的局部X坐标(厘米) |
| | | * @param localYB 点B的局部Y坐标(厘米) |
| | | * @return 字符串数组: |
| | | * [0] 十进制度纬度, |
| | | * [1] 十进制度经度, |
| | | * [2] 度分格式纬度, |
| | | * [3] 度分格式经度 |
| | | * @param localX 局部X坐标(厘米) |
| | | * @param localY 局部Y坐标(厘米) |
| | | * @param latA 点A的纬度(度分格式) |
| | | * @param lonA 点A的经度(度分格式) |
| | | * @param latB 点B的纬度(度分格式) |
| | | * @param lonB 点B的经度(度分格式) |
| | | * @param localXA 点A的局部X坐标(厘米) |
| | | * @param localYA 点A的局部Y坐标(厘米) |
| | | * @param localXB 点B的局部X坐标(厘米) |
| | | * @param localYB 点B的局部Y坐标(厘米) |
| | | * @return 字符串数组: |
| | | * [0] 十进制度纬度, |
| | | * [1] 十进制度经度, |
| | | * [2] 度分格式纬度, |
| | | * [3] 度分格式经度 |
| | | */ |
| | | public static String[] convertLocalToGlobalCoordinates( |
| | | String localX, String localY, |
| | |
| | | double localXA, double localYA, |
| | | double localXB, double localYB) { |
| | | |
| | | // 1. 计算坐标系转换参数 |
| | | // 1. 计算坐标系转换参数 |
| | | double[] transformParams = CoordinateTranslator.computeTransformParamsWithTwoPoints( |
| | | latA, lonA, latB, lonB, localXA, localYA, localXB, localYB); |
| | | |
| | | // 2. 解析输入坐标并转换为米 |
| | | // 2. 解析输入坐标并转换为米 |
| | | double x = Double.parseDouble(localX) / 100.0; |
| | | double y = Double.parseDouble(localY) / 100.0; |
| | | |
| | | // 3. 从转换参数中提取必要信息 |
| | | double originEasting = transformParams[0]; // 原点东坐标(米) |
| | | double originNorthing = transformParams[1]; // 原点北坐标(米) |
| | | double cosTheta = transformParams[2]; // 旋转矩阵cos分量 |
| | | double sinTheta = transformParams[3]; // 旋转矩阵sin分量 |
| | | double zone = transformParams[5]; // UTM带号 |
| | | // 3. 从转换参数中提取必要信息 |
| | | double originEasting = transformParams[0]; // 原点东坐标(米) |
| | | double originNorthing = transformParams[1]; // 原点北坐标(米) |
| | | double cosTheta = transformParams[2]; // 旋转矩阵cos分量 |
| | | double sinTheta = transformParams[3]; // 旋转矩阵sin分量 |
| | | double zone = transformParams[5]; // UTM带号 |
| | | |
| | | // 4. 将局部坐标转换为UTM坐标 |
| | | // 4. 将局部坐标转换为UTM坐标 |
| | | double[] utmCoordinates = convertLocalToUtm(x, y, originEasting, originNorthing, cosTheta, sinTheta); |
| | | |
| | | // 5. 将UTM坐标转换为经纬度 |
| | | // 5. 将UTM坐标转换为经纬度 |
| | | double[] latLng = convertUtmToWgs84(utmCoordinates[0], utmCoordinates[1], zone); |
| | | |
| | | // 6. 准备结果数组 |
| | | // 6. 准备结果数组 |
| | | String[] result = new String[4]; |
| | | result[0] = COORDINATE_FORMAT.format(latLng[0]); // 十进制度纬度 |
| | | result[1] = COORDINATE_FORMAT.format(latLng[1]); // 十进制度经度 |
| | | result[0] = COORDINATE_FORMAT.format(latLng[0]); // 十进制度纬度 |
| | | result[1] = COORDINATE_FORMAT.format(latLng[1]); // 十进制度经度 |
| | | |
| | | // 7. 转换为度分格式 |
| | | // 7. 转换为度分格式 |
| | | double latDegMin = convertDecimalToDegMin(latLng[0]); |
| | | double lngDegMin = convertDecimalToDegMin(latLng[1]); |
| | | result[2] = COORDINATE_FORMAT.format(latDegMin); // 度分格式纬度 |
| | | result[3] = COORDINATE_FORMAT.format(lngDegMin); // 度分格式经度 |
| | | result[2] = COORDINATE_FORMAT.format(latDegMin); // 度分格式纬度 |
| | | result[3] = COORDINATE_FORMAT.format(lngDegMin); // 度分格式经度 |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 将十进制度转换为度分格式 |
| | | * @param decimalDegrees 十进制度坐标值 |
| | | * @return 度分格式坐标值 (dddmm.mmmm) |
| | | * 将十进制度转换为度分格式 |
| | | * @param decimalDegrees 十进制度坐标值 |
| | | * @return 度分格式坐标值 (dddmm.mmmm) |
| | | */ |
| | | private static double convertDecimalToDegMin(double decimalDegrees) { |
| | | double degrees = Math.floor(decimalDegrees); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 将局部坐标转换为UTM坐标 |
| | | * 将局部坐标转换为UTM坐标 |
| | | * |
| | | * @param localX 局部坐标系X值(米) |
| | | * @param localY 局部坐标系Y值(米) |
| | | * @param originEasting 原点东坐标(米) |
| | | * @param originNorthing 原点北坐标(米) |
| | | * @param cosTheta 旋转矩阵cos分量 |
| | | * @param sinTheta 旋转矩阵sin分量 |
| | | * @return UTM坐标数组 [东坐标, 北坐标] |
| | | * @param localX 局部坐标系X值(米) |
| | | * @param localY 局部坐标系Y值(米) |
| | | * @param originEasting 原点东坐标(米) |
| | | * @param originNorthing 原点北坐标(米) |
| | | * @param cosTheta 旋转矩阵cos分量 |
| | | * @param sinTheta 旋转矩阵sin分量 |
| | | * @return UTM坐标数组 [东坐标, 北坐标] |
| | | */ |
| | | private static double[] convertLocalToUtm( |
| | | double localX, double localY, |
| | | double originEasting, double originNorthing, |
| | | double cosTheta, double sinTheta) { |
| | | |
| | | // 交换XY坐标(局部坐标系通常以Y为前进方向) |
| | | // 交换XY坐标(局部坐标系通常以Y为前进方向) |
| | | double rotatedX = localY; |
| | | double rotatedY = localX; |
| | | |
| | | // 应用旋转和平移变换 |
| | | // 应用旋转和平移变换 |
| | | double dx = cosTheta * rotatedX + sinTheta * rotatedY; |
| | | double dy = -sinTheta * rotatedX + cosTheta * rotatedY; |
| | | |
| | | return new double[] { |
| | | dx + originEasting, // 东坐标 |
| | | dy + originNorthing // 北坐标 |
| | | dx + originEasting, // 东坐标 |
| | | dy + originNorthing // 北坐标 |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * 将UTM坐标转换为WGS84经纬度 |
| | | * 将UTM坐标转换为WGS84经纬度 |
| | | * |
| | | * @param easting UTM东坐标(米) |
| | | * @param northing UTM北坐标(米) |
| | | * @param zone UTM带号 |
| | | * @return 经纬度数组 [纬度, 经度] (十进制度) |
| | | * @param easting UTM东坐标(米) |
| | | * @param northing UTM北坐标(米) |
| | | * @param zone UTM带号 |
| | | * @return 经纬度数组 [纬度, 经度] (十进制度) |
| | | */ |
| | | public static double[] convertUtmToWgs84(double easting, double northing, double zone) { |
| | | return utm2ll_wgs84(easting, northing, zone); |
| | | } |
| | | |
| | | /** |
| | | * UTM坐标转WGS84经纬度实现 |
| | | * UTM坐标转WGS84经纬度实现 |
| | | */ |
| | | private static double[] utm2ll_wgs84(double x, double y, double f) { |
| | | double[] latlon = new double[2]; |
| | | double A1 = 6378137.0; |
| | | double F1 = 298.257223563; |
| | | |
| | | // 常量定义 |
| | | // 常量定义 |
| | | double D0 = 180 / Math.PI; |
| | | double maxiter = 100; |
| | | double eps = 1e-11; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 计算UTM转换系数 |
| | | * 计算UTM转换系数 |
| | | */ |
| | | private static double[] coef(double e, int m) { |
| | | double[][] c0; |