前言:
GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。
- 我这里主要是用作:autocad的
xxx.dxf格式文件转成xxx.geojson格式文件。 - 思路:
gdal是c++写的,安装调用它可以用命令行,也可以集成到java项目上。所以首先要在web服务器上安装gdal,然后把gdal提供的jar依赖引到java项目中,并且把gdal的一些动态链接库(win系统是.dll文件,linux是.so文件)给到jdk去调用。
我这里是本地开发,所以本文记录的是本地windows系统上搭环境。
linux系统,请参考:linux 安装 GDAL 3.3.2 - 简书 (jianshu.com) 
一、下载
下载gdal windows版本64位最新的稳定版,前往:GISInternals Support Site


二、安装gdal
双击打开:
选择custom安装即可。
三、配置环境变量
Note: In order to have the bindings work the location of the core components must be included manually in the PATH environment variable.
- a.系统变量-path中新增:
C:\Program Files\GDAL\ - b.系统变量-新增-变量名:
GDAL_DATA,变量值:C:\Program Files\GDAL\gdal-data - c.系统变量-新增-变量名:
GDAL_DRIVER_PATH,变量值:C:\Program Files\GDAL\gdalplugins
测试gdal安装是否成功,cmd输入:
# gdalinfo --version
image.png 
四、java集成gdal
说明:
java集成gdal主要是引gdal.jar依赖以及配置jdk可以调用到.dll动态链接库。
引jar包可以有很多种方式,比如:
- 直接引入(不推荐);
 - 打到本地maven仓库之后pom.xml引入(推荐);
 - jar包复制到
src/main/resources/下,直接在pom.xml中引入(最简单推荐,下文说的就是这种); 
步骤:
- 本地使用springboot自建web应用,maven作为项目管理和构建工具;
 - 把C:\Program Files\GDAL\下所有的.dll文件全部复制到jdk/bin/下;
 - 
把C:\Program Files\GDAL\java\下的gdal.jar和C:\Program Files\GDAL\下的gdalalljni.dll复制到src/main/resources/gdal/win32/下;
如图:
image.png 
注意的就是linux的jar包和win32的jar包可能不一样,linux的要去下载gdal二进制资源然后编译等,而且第2第3部应用动态链接库也完全不一样,后期我再验证更新。我这里先说下win的开发环境配置。
- pom.xml中引入gdal.jar包:
 
<properties>
        ...
        <gdal.binddir>src/main/resources/gdal/win32</gdal.binddir>
    </properties>
<dependencies>
        <dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.5.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/${gdal.binddir}/gdal.jar</systemPath>
        </dependency>
</dependencies>
- 
测试dxf文件转geojson。
说明:把.dxf转成.geojson,转换后的geojson可读性很强导致文件过大,所以我使用分页分文件夹去转换,详情见测试代码源码。
image.png
效果:
image.png
image.png
image.png 
源码:
说明:源码中涉及到下面几点的可以先忽略注释或者删掉
- 转换可能导致中文乱码,我这里在源码注掉了本篇不涉及,可以参见我这篇文章:GDAL 在把 dxf 转成 geojson 后,cad的图层名中文乱码问题 - 简书 (jianshu.com)
 - 在FileUtil.java中可以看到main方法里有个dealDxf(path, inputFileName);方法,是手动处理个别cad图转换报错的问题,
原因:查看gdal的c++源码,在解析dxf中的id字符串属性长度超长报错,dxf实际就是个文本查看它发现里面有个别元素的id字符串过长,而且是重复有规律的(类似于在同文件夹下一直复制同一个文件windows会自动给新文件重命名),猜测是制图师在编辑cad时无脑复制粘贴某些元素导致。
解决:用计数的方式去处理这种超长id,如:把 id_1_1 转成 id_002,把 id_1_1_1_1 转成 id_004,把 id_1_1_1_1_1_1_1_1_1_1_1_1 转成 id_012。 
- pom.xml:
 
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ckk</groupId>
    <artifactId>gismap</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <gdal.binddir>src/main/resources/gdal/win32</gdal.binddir>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.5.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/${gdal.binddir}/gdal.jar</systemPath>
        </dependency>
        <!--  编码检测依赖:cpdetector、antlr、chardet、jargs      -->
<!--        <dependency>-->
<!--            <groupId>com.hongyi</groupId>-->
<!--            <artifactId>cpdetector</artifactId>-->
<!--            <version>1.0.10</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>com.hongyi</groupId>-->
<!--            <artifactId>antlr</artifactId>-->
<!--            <version>2.7.4</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>com.hongyi</groupId>-->
<!--            <artifactId>chardet</artifactId>-->
<!--            <version>1.0</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>com.hongyi</groupId>-->
<!--            <artifactId>jargs</artifactId>-->
<!--            <version>1.0</version>-->
<!--        </dependency>-->
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.0-alpha7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.2</version>
        </dependency>
    </dependencies>
</project>
- test.java:
 
package test;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.gdal;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.*;
import org.gdal.osr.SpatialReference;
import util.file.FileUtil;
/**
 * gdal测试类
 * @author ckk
 * @create 2022-08-06 16:07
 **/
public class Test {
    public static void main(String[] args) {
        // 1.dxf 转 geojson
        boolean b = dxf2GeoJson("D:\\cad2wms\\", "葫芦素-最新.dxf", "D:\\cad2wms\\hulusu_colliery_id\\");
        System.out.println("bbbbbb==="+b);
    }
    /**
     * dxf转geojson(矢量拆分)
     * @param inputPath
     * @param cadFileName
     * @param outputPath
     * @return
     */
    public static boolean dxf2GeoJson(String inputPath, String cadFileName, String outputPath){
        try {
            ogr.RegisterAll();
            // gdal.SetConfigOption 选项配置参见:https://trac.osgeo.org/gdal/wiki/ConfigOptions
            // 为了支持中文路径,请添加下面这句代码
            gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            // 为了使属性表字段支持中文,请添加下面这句
            gdal.SetConfigOption("SHAPE_ENCODING", "");
            /**
             * 判断编码dxf文件编码类型:
             * 在cad另存为dxf时,由于不同版本问题导致编码不同。
             * 已知:dxf >=2007 版本编码为 UTF-8,其他低版本编码为 GB2312
             * 若为 UTF-8 需要设置:gdal.SetConfigOption("DXF_ENCODING", "ASCII");
             */
//            String charset = EncodingDetector.getCharset(new File(inputPath + cadFileName));
                        
                        
                            
                        
                        
                            联系我们
                            ,获取更多内容