java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java坐标互转

Java实现WGS84/GCJ02/BD09的坐标互转终极方案

作者:寒冰碧海

这篇文章主要为大家详细介绍了Java如何利用Geotools实现WGS84/GCJ02/BD09的坐标互转,文中的示例代码讲解详细,需要的小伙伴可以了解下

工具类设计目标

为简化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库的版本兼容性

扩展应用场景

参考文档GeoTools官方文档

引用说明:本文实现参考了GeoTools核心转换逻辑,并结合笑脸坐标转换工具的设计思想优化异常处理流程。

到此这篇关于Java实现WGS84/GCJ02/BD09的坐标互转终极方案的文章就介绍到这了,更多相关Java坐标互转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文