写在最前

1. 集成GDAL

这只是 Java 项目的集成部分。在开发或部署环境中,还需要在系统中安装 GDAL 的二进制程序,并正确配置相关环境变量,才能让 Java 识别并调用它。
换句话说,Java 只是通过接口调用系统中已安装的 GDAL,而不是自带完整实现。仅仅引入 GDAL 的 Java 依赖包并不能正常工作,这是一种常见的误解。

<!-- GDAL Java Bindings -->
<dependency>
   <groupId>org.gdal</groupId>
   <artifactId>gdal</artifactId>
   <version>3.2.0</version>
</dependency>

1.1 window 部署

在开发阶段我们都使用window来进行开发,我们可以到此下载对应的安装包 https://www.gisinternals.com/sdk.php 下载解压到你期望的目录中即可。

在 Windows 系统中,还需要配置相关的环境变量。其中 Path 是系统默认存在的变量,直接在其中新项即可。而 PROJ_LIB 变量需要手动新建,并设置为 GDAL 中 proj 数据目录的路径。

Path

  • F:\software\release-1900-x64-dev\release-1900-x64\bin\gdal\java

  • F:\software\release-1900-x64-dev\release-1900-x64\bin

PROJ_LIB

  • F:\software\release-1900-x64-dev\release-1900-x64\bin\proj6\share

需要特别注意的是,如果你安装的是 较高版本的 GDAL,在 Java 启动或日志中输出的版本号必须对应正确的 GDAL Java 依赖。例如日志中出现:✅ GDAL 初始化成功,版本: 3020300

这里的 3020300 表示 GDAL 的版本为 3.2.0 ,GDAL Java 包的版本必须与系统中安装的 GDAL 二进制版本一致,否则会出现兼容性问题或加载失败。请根据输出的版本号在下方链接中选择对应的 GDAL Java 依赖版本

https://mvnrepository.com/artifact/org.gdal/gdal

package com.tanqidi.survey.service;

import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.gdal.osr.CoordinateTransformation;
import org.gdal.osr.SpatialReference;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * GDAL 地理数据转换服务
 * 使用 GDAL Java 绑定进行高性能的地理数据格式转换
 * 
 * 支持格式:
 * - KML/KMZ → GeoJSON
 * - Shapefile (ZIP) → GeoJSON
 * - GeoJSON → KML
 * - GeoJSON → Shapefile
 * 
 * 优势:
 * - 性能:比 GeoTools 快 10-50 倍
 * - 内存:内存占用降低 10-20 倍
 * - 标准:行业标准,兼容性最好
 * 
 * @author tanqidi
 */
@Slf4j
@Service
public class GdalGeoConverterService {
    
    private volatile boolean gdalInitialized = false;
    
    /**
     * 初始化 GDAL
     */
    @PostConstruct
    public void init() {
        try {
            // 注册所有 GDAL 驱动
            ogr.RegisterAll();
            gdal.AllRegister();
            
            // 设置配置选项
            gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
            
            // 强制使用传统 GIS 轴序(经度,纬度)而不是 EPSG 定义的轴序
            // 这确保 GeoJSON 输出符合 RFC 7946 标准(经度在前)
            gdal.SetConfigOption("OSR_DEFAULT_AXIS_MAPPING_STRATEGY", "TRADITIONAL_GIS_ORDER");
            
            String version = gdal.VersionInfo("VERSION_NUM");
            log.info("✅ GDAL 初始化成功,版本: {}", version);
            
            gdalInitialized = true;
            
        } catch (UnsatisfiedLinkError e) {
            log.warn("⚠️ GDAL 本地库未找到,将使用 GeoTools 作为后备方案");
            log.warn("⚠️ 如需使用 GDAL,请安装 GDAL 本地库: {}", e.getMessage());
            gdalInitialized = false;
        } catch (Exception e) {
            log.error("❌ GDAL 初始化失败: {}", e.getMessage(), e);
            gdalInitialized = false;
        }
    }
    
    /**
     * 检查 GDAL 是否可用
     */
    public boolean isGdalAvailable() {
        return gdalInitialized;
    }
}

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.5.0)

2025-10-11 10:31:12.760 INFO  [main] com.tanqidi.survey.SurveyServiceApplication: Starting SurveyServiceApplication using Java 21.0.4 with PID 9664 (F:\idea_code\survey-service\target\classes started by 17297 in F:\idea_code\survey-service)
2025-10-11 10:31:12.767 INFO  [main] com.tanqidi.survey.SurveyServiceApplication: No active profile set, falling back to 1 default profile: "default"
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.5.5 
2025-10-11 10:31:14.389 INFO  [main] com.tanqidi.survey.service.GdalGeoConverterService: ✅ GDAL 初始化成功,版本: 3020300
2025-10-11 10:31:15.380 INFO  [main] com.tanqidi.survey.SurveyServiceApplication: Started SurveyServiceApplication in 2.893 seconds (process running for 3.683)

1.2 linux 部署

2. 使用方式

2.1 将 KML 内容转换为 GeoJSON

写在最后