Java實現(xiàn)WGS84/GCJ02/BD09的坐標互轉終極方案
工具類設計目標
為簡化GIS開發(fā)中頻繁的坐標轉換操作,本文封裝可復用的Java工具類,實現(xiàn)以下能力:
多坐標系互轉(WGS84/GCJ02/BD09/UTM等)
線程安全的靜態(tài)方法調用
自動處理坐標軸順序(經度優(yōu)先/緯度優(yōu)先)
異常捕獲與日志追蹤
核心源碼實現(xiàn)
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);
// 創(chuàng)建帶高程的坐標點(x,y,z)
Coordinate sourceCoord = new Coordinate(coordinate.x, coordinate.y, coordinate.z);
// 構建三維坐標轉換管道
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
Coordinate targetCoord = new Coordinate();
// 執(zhí)行坐標轉換(自動處理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);
// 執(zhí)行轉換
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帶
);
關鍵特性說明
| 特性 | 實現(xiàn)方案 | 圖標 |
|---|---|---|
| 坐標系兼容性 | 支持5000+ EPSG標準坐標系 | ?? |
| 性能優(yōu)化 | 緩存CRS對象避免重復解碼 | ? |
| 異常處理 | 統(tǒng)一捕獲Factory/Transform異常 | ?? |
| 日志追蹤 | 通過@Slf4j記錄詳細錯誤信息 | ?? |
注意事項
坐標軸順序
GeoTools默認采用經度,緯度順序,通過CRS.decode(code, true)強制指定軸順序
精度損失
高精度場景建議使用PrecisionModel配置計算精度
依賴沖突
注意GeoTools與其他GIS庫的版本兼容性
擴展應用場景
- 批量轉換:結合CSV文件實現(xiàn)海量數(shù)據(jù)轉換
- GIS系統(tǒng)集成:與GeoServer等平臺對接
- 移動端適配:封裝為RESTful API服務
參考文檔:GeoTools官方文檔
引用說明:本文實現(xiàn)參考了GeoTools核心轉換邏輯,并結合笑臉坐標轉換工具的設計思想優(yōu)化異常處理流程。
到此這篇關于Java實現(xiàn)WGS84/GCJ02/BD09的坐標互轉終極方案的文章就介紹到這了,更多相關Java坐標互轉內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
IntelliJ IDEA右鍵文件夾沒有Java Class文件的原因及解決方法
這篇文章主要介紹了IntelliJ IDEA右鍵文件夾沒有Java Class文件的原因及解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
Java用BigDecimal類解決Double類型精度丟失的問題
這篇文章主要介紹了Java用BigDecimal類解決Double類型精度丟失的問題,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12
Java并發(fā)系列之AbstractQueuedSynchronizer源碼分析(獨占模式)
這篇文章主要為大家詳細介紹了Java并發(fā)系列之AbstractQueuedSynchronizer源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-02-02

