package com.se.nsl.utils;
|
|
import org.gdal.gdal.gdal;
|
import org.gdal.osr.CoordinateTransformation;
|
import org.gdal.osr.SpatialReference;
|
import org.gdal.osr.osr;
|
|
public class CoordinateTransformer {
|
|
// static {
|
// try {
|
// gdal.AllRegister();
|
// } catch (Exception e) {
|
// System.err.println("GDAL驱动注册失败: " + e.getMessage());
|
// }
|
// }
|
|
public static double[] transform(int sourceEPSG, int targetEPSG,
|
double x, double y, double z) {
|
SpatialReference sourceSRS = null;
|
SpatialReference targetSRS = null;
|
CoordinateTransformation ct = null;
|
|
try {
|
// 创建源坐标系
|
sourceSRS = new SpatialReference();
|
int sourceResult = sourceSRS.ImportFromEPSG(sourceEPSG);
|
if (sourceResult != 0) {
|
throw new IllegalArgumentException("无效的源EPSG代码: " + sourceEPSG);
|
}
|
|
// 创建目标坐标系
|
targetSRS = new SpatialReference();
|
int targetResult = targetSRS.ImportFromEPSG(targetEPSG);
|
if (targetResult != 0) {
|
throw new IllegalArgumentException("无效的目标EPSG代码: " + targetEPSG);
|
}
|
|
sourceSRS.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
targetSRS.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
|
// 创建坐标转换对象
|
ct = new CoordinateTransformation(sourceSRS, targetSRS);
|
double[] result = ct.TransformPoint(x, y, z);
|
|
if (result == null || Double.isNaN(result[0]) || Double.isNaN(result[1])) {
|
throw new IllegalArgumentException("坐标转换失败,可能是坐标系不兼容");
|
}
|
|
return result;
|
} finally {
|
// 确保资源被释放
|
if (ct != null) ct.delete();
|
if (targetSRS != null) targetSRS.delete();
|
if (sourceSRS != null) sourceSRS.delete();
|
}
|
}
|
|
public static double[] transform(int sourceEPSG, int targetEPSG, double x, double y) {
|
return transform(sourceEPSG, targetEPSG, x, y, 0.0);
|
}
|
|
public static double[] transform(String sourceWKT, String targetWKT,
|
double x, double y, double z) {
|
SpatialReference sourceSRS = null;
|
SpatialReference targetSRS = null;
|
CoordinateTransformation ct = null;
|
|
try {
|
// 创建源坐标系
|
sourceSRS = new SpatialReference();
|
int sourceResult = sourceSRS.ImportFromWkt(sourceWKT);
|
if (sourceResult != 0) {
|
throw new IllegalArgumentException("无效的源WKT定义");
|
}
|
|
// 创建目标坐标系
|
targetSRS = new SpatialReference();
|
int targetResult = targetSRS.ImportFromWkt(targetWKT);
|
if (targetResult != 0) {
|
throw new IllegalArgumentException("无效的目标WKT定义");
|
}
|
|
// 创建坐标转换对象
|
ct = new CoordinateTransformation(sourceSRS, targetSRS);
|
double[] result = ct.TransformPoint(x, y, z);
|
|
if (result == null || Double.isNaN(result[0]) || Double.isNaN(result[1])) {
|
throw new IllegalArgumentException("坐标转换失败,可能是坐标系不兼容");
|
}
|
|
return result;
|
} finally {
|
// 确保资源被释放
|
if (ct != null) ct.delete();
|
if (targetSRS != null) targetSRS.delete();
|
if (sourceSRS != null) sourceSRS.delete();
|
}
|
}
|
|
public static void main(String[] args) {
|
try {
|
double[] result1 = transform(4326, 32650, 116.4074, 39.9042); // 北京
|
System.out.printf("WGS84 -> UTM 50N: (%.6f, %.6f, %.2f)%n",
|
result1[0], result1[1], result1[2]);
|
|
double[] result2 = transform(4326, 3857, 116.4074, 39.9042); // 北京
|
System.out.printf("WGS84 -> Web Mercator: (%.6f, %.6f, %.2f)%n",
|
result2[0], result2[1], result2[2]);
|
|
// 使用适合NAD83 California zone 5的坐标
|
double[] result3 = transform(4326, 26945, -122.4194, 37.7749); // 旧金山
|
System.out.printf("WGS84 -> NAD83 California zone 5: (%.6f, %.6f, %.2f)%n",
|
result3[0], result3[1], result3[2]);
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|