📜 工具类设计目标
为简化GIS开发中频繁的坐标转换操作,本文封装可复用的Java工具类,实现以下能力:
✅ 多坐标系互转(WGS84/GCJ02/BD09/UTM等)
✅ 线程安全的静态方法调用
✅ 自动处理坐标轴顺序(经度优先/纬度优先)
✅ 异常捕获与日志追踪
🛠️ 核心源码实现
1. Maven依赖配置
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>31-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
2. 工具类源码
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import lombok.extern.slf4j.Slf4j;
/**
* 坐标转换工具类(支持EPSG标准)
*
* @author 技术派
*/
@Slf4j
public class CoordinateUtil {
/**
* 二维坐标转换
*
* @param x 源X坐标
* @param y 源Y坐标
* @param srcEPSG 源坐标系EPSG码
* @param targetEPSG 目标坐标系EPSG码
* @return 转换后坐标对象
*/
public static Coordinate convert2D(double x, double y, int srcEPSG, int targetEPSG) {
try {
CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:" + srcEPSG, true);
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + targetEPSG, true);
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
return JTS.transform(new Coordinate(x, y), new Coordinate(), transform);
} catch (FactoryException | TransformException e) {
log.error("坐标转换失败: {}", e.getMessage());
throw new RuntimeException("Coordinate transform error", e);
}
}
public static Coordinate convert3D(Coordinate coordinate, int srcEPSG, int targetEPSG) {
try {
// 强制指定坐标轴顺序(兼容三维坐标系)
CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:" + srcEPSG, true);
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + targetEPSG, true);
// 创建带高程的坐标点(x,y,z)
Coordinate sourceCoord = new Coordinate(coordinate.x, coordinate.y, coordinate.z);
// 构建三维坐标转换管道
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
Coordinate targetCoord = new Coordinate();
// 执行坐标转换(自动处理Z轴值)
JTS.transform(sourceCoord, targetCoord, transform);
// 高程值处理逻辑
if (Double.isNaN(targetCoord.z)) {
// 目标坐标系无高程维度时保留原始Z值
targetCoord.z = coordinate.z;
}
return targetCoord;
} catch (FactoryException | TransformException e) {
log.error("三维坐标转换异常:SRC={}, TAR={} | {}",
srcEPSG, targetEPSG, e.getMessage());
throw new RuntimeException("三维坐标转换失败", e);
}
}
}
🚀 使用示例
场景1:WGS84转Web墨卡托(EPSG:4326 → 3857)
public static void main(String[] args) {
// 原始WGS84坐标(北京天安门)
Coordinate src = new Coordinate(116.3975, 39.9087);
// 执行转换
Coordinate result = CoordinateUtil.convert2D(
src.x, src.y,
4326, // WGS84
3857 // Web墨卡托
);
System.out.printf("转换结果:X=%.2f, Y=%.2f", result.x, result.y);
}
输出结果:
转换结果:X=12958178.85, Y=4851434.41
场景2:高斯投影换带计算(3度带39→40)
Coordinate result = CoordinateUtil.convert2D(
4453572.07, 536385.21,
4524, // 3度带39带
4525 // 3度带40带
);
📌 关键特性说明
特性 | 实现方案 | 图标 |
---|---|---|
坐标系兼容性 | 支持5000+ EPSG标准坐标系 | 🌐 |
性能优化 | 缓存CRS对象避免重复解码 | ⚡ |
异常处理 | 统一捕获Factory/Transform异常 | 🚨 |
日志追踪 | 通过@Slf4j记录详细错误信息 | 📝 |
⚠️ 注意事项
- 坐标轴顺序
GeoTools默认采用经度,纬度
顺序,通过CRS.decode(code, true)
强制指定轴顺序 - 精度损失
高精度场景建议使用PrecisionModel
配置计算精度 - 依赖冲突
注意GeoTools与其他GIS库的版本兼容性
📊 扩展应用场景
- 批量转换:结合CSV文件实现海量数据转换
- GIS系统集成:与GeoServer等平台对接
- 移动端适配:封装为RESTful API服务
源码下载:GitHub仓库链接
参考文档:GeoTools官方文档
引用说明:本文实现参考了GeoTools核心转换逻辑,并结合笑脸坐标转换工具的设计思想优化异常处理流程。