java gdal 将geojson批量导入到 gdb(FileGeodatabase)文件中

需求

需要将地块的geojson数据导入到gdb文件中

思路

为了方便后期使用和集成,于是采用java(或者C#)的方式,利用gdal创建gdb文件并将geojson数据导入其中

linux平台使用

环境

win10、IDEA 2022

实现过程

1、文件准备

   gdal下载地址:https://www.gisinternals.com/archive.php

   我使用的版本:release-1900-x64-gdal-3-0-4-mapserver-7-4-3.zip

   下载gdal开发文件和创建gdb的驱动文件:

 

2、开发环境搭建

    借鉴:https://blog.csdn.net/yelangkingwuzuhu/article/details/128161948

   1)、安装gdal-300-1900-x64-filegdb.msi文件,安装后找到对应文件夹,将gdadlplugins文件夹和FileGDBAPI.dll文件拷贝到release-1900-x64-gdal-3-0-4-mapserver-7-4-3文件夹下的bin文件夹下

 

 

 2)、设置环境变量

借鉴:https://www.cnblogs.com/hjyjack9563-bk/p/17431643

设置GDAL环境变量

 在系统变量Path中设置gdal的bin目录:

 添加FileGDB驱动环境变量,借鉴:https://blog.csdn.net/yelangkingwuzuhu/article/details/128161948

 

为开发过程中涉及创建图层坐标系,需要使用proj.db,需要设置PROJ_LIB环境变量:D:\software\release-1900-x64-gdal-3-0-4-mapserver-7-4-3\bin\proj6\share,如下所示:

3)、将下载程序中的bin\gdal\java路径下的gdalalljni.dll拷贝到jdkbin目录下,如下图所示

 4)、在IDEA中创建一个JAVA项目,在项目根目录创建lib目录,将下载程序中的bin\gdal\java路径下的gdal.jar复制到lib文件夹下。

 

 5)、借鉴:https://www.cnblogs.com/youzi-xuchongyou/p/17761719

添加gdal.jar到 工程库中,如下图所示:

在pom.xml中的dependencies节点添加gdal.jar包引用:

        <dependency>
           <groupId>org.gdal</groupId>
           <artifactId>gdal</artifactId>
           <version>3.0.4</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/gdal.jar</systemPath>
        </dependency>

 

3、编写代码

gdal环境配置

如果报错就看文章最后写的 

    /**
    * geoJsonPath 文件路径
    * saveGdbPath 生成的gdb文件路径
    * */
    public  static  String CreateFileGDB(String geoJsonPath,String saveGdbPath){
        String result="";
        try{
            // 注册所有的驱动
            gdal.AllRegister();
            // 为了支持中文路径,请添加下面这句代码
            gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            // 为了使属性表字段支持中文,请添加下面这句
            gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
            SpatialReference sr = new SpatialReference();
            sr.ImportFromEPSG(4326);
            ogr.RegisterAll();
//            int count =ogr.GetDriverCount();
//            System.out.println(count);
//            for(int i=0; i<count; i++){
//                System.out.println(ogr.GetDriver(i).GetName());
//            }
            org.gdal.ogr.Driver oDriver = ogr.GetDriverByName("FileGDB");
            if (oDriver == null) {
                System.out.println("FileGDB" + " 驱动不可用!\n");
                return "FileGDB驱动不可用";
            }
            List<String> geojsons=new ArrayList<>();
            geojsons.add(geoJsonPath);
            result=importGeojsonsToGdb(geojsons,saveGdbPath);
            if(result.equals("")){
                result= "创建成功";
            }
        }catch (Exception ex){
            result="创建失败"+ex.getMessage();
        }
         return  result;
    }

 

 

 

 通过geojson路径生成gdb文件:

   private static String importGeojsonsToGdb(List<String> inputGeojsonfiles, String gdbFilePath)
    {
        String result = "";
        try
        {
            Path directoryPath = Paths.get(gdbFilePath);
            if(Files.exists(directoryPath)){
                deleteRecursively(new File(gdbFilePath));
            }
            // 创建或打开GDB文件
            String driverName = "FileGDB";
            org.gdal.ogr.Driver gdbDriver = ogr.GetDriverByName(driverName);
            if (gdbDriver == null)
            {
                return "无法找到FileGDB驱动";

            }
            DataSource gdbDataSource = gdbDriver.CreateDataSource(gdbFilePath, null);
            if (gdbDataSource == null)
            {
                return "无法创建或打开GDB文件";
            }
            // 获取第一个输入图层的结构(作为输出图层的模板)
            DataSource firstInputDataSource = ogr.Open(inputGeojsonfiles.get(0), 0);
            if (firstInputDataSource == null)
            {
                result = "读取失败: " + inputGeojsonfiles.get(0);
                return result;
            }
            Layer firstInputLayer = firstInputDataSource.GetLayerByIndex(0);
            if (firstInputLayer == null)
            {
                result ="获取图层失败: " + inputGeojsonfiles.get(0);
                return result;
            }

            // 合并所有输入 Shapefile 的要素
            for (String inputShapefile : inputGeojsonfiles)
            {
                // 1. 先拿到文件名(含扩展名)
                String filePath = new File(inputShapefile).getName(); // "file.txt"

                // 2. 去除扩展名
                String fileName = filePath.contains(".")
                        ? filePath.substring(0, filePath.lastIndexOf('.'))
                        : filePath;
                // 在GDB中创建相同的图层
                Layer gdbLayer = gdbDataSource.CreateLayer(fileName, firstInputLayer.GetSpatialRef(), firstInputLayer.GetGeomType(), null);
                if (gdbLayer == null)
                {
                    return "无法在GDB中创建图层";
                }

                // 复制字段定义
                FeatureDefn inputLayerDef = firstInputLayer.GetLayerDefn();
                for (int i = 0; i < inputLayerDef.GetFieldCount(); i++)
                {
                    FieldDefn fieldDef = inputLayerDef.GetFieldDefn(i);
                    if (gdbLayer.CreateField(fieldDef, 1) != ogr.OGRERR_NONE)
                    {
                        result = "无法创建字段: " + fieldDef.GetName();
                        return result;
                    }
                }
                DataSource inputDataSource = ogr.Open(inputShapefile, 0);
                if (inputDataSource == null)
                {
                    result="打开文件失败: " + inputShapefile;
                    return result;
                }

                Layer inputLayer = inputDataSource.GetLayerByIndex(0);
                if (inputLayer == null)
                {
                    result = "获取图层失败: " + inputShapefile;
                    return result;
                }

                // 复制要素
                inputLayer.ResetReading();
                Feature inputFeature;
                while ((inputFeature = inputLayer.GetNextFeature()) != null)
                {
                    Feature outputFeature = new Feature(gdbLayer.GetLayerDefn());
                    outputFeature.SetGeometry(inputFeature.GetGeometryRef());

                    // 复制字段值
                    for (int i = 0; i < inputLayerDef.GetFieldCount(); i++)
                    {
                        outputFeature.SetField(i, inputFeature.GetFieldAsString(i));
                    }

                    if (gdbLayer.CreateFeature(outputFeature) != ogr.OGRERR_NONE)
                    {
                        return "复制要素到gdb失败";
                    }
                }
                // 释放输入数据源
                inputDataSource.delete();
            }
            // 释放资源
            firstInputDataSource.delete();
            gdbDataSource.delete();
        }
        catch (Exception ex)
        {
            result = ex.getMessage();
        }
        return result;
    }
    private static void deleteRecursively(File file) {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                deleteRecursively(child);
            }
        }
        file.delete(); // 删除文件或空文件夹
    }

4、注意事项

1)、Native library load failed.
java.lang.UnsatisfiedLinkError: no gdalalljni in java.library.path

说明gdalalljni.dll没有放到正确的目录,需要将gdalalljni.dll放到jdkbin目录下,参考2->3)节点。

或者设置gdalalljni.dll的环境变量

  • 打开 系统环境变量设置

  • 找到 PATH 变量,点击编辑

  • 添加一行:

    D:\software\release-1900-x64-gdal-3-0-4-mapserver-7-4-3\bin\gdal\java

2)、ogr.GetDriverByName("FileGDB")获取为空 或者 FileGDB驱动不可用

说明GDAL_DRIVER_PATH环境变量没有正确配置,参考2->1)和 2->2)节点

可以使用下面代码遍历gdal支持的驱动,如果没有出现FileGDB说明没有配置成功,如下图所示:

            int count =ogr.GetDriverCount();
            System.out.println(count);
            for(int i=0; i<count; i++){
                System.out.println(ogr.GetDriver(i).GetName());
            }

 

posted on 2025-04-18 14:49  Geography爱好者  阅读(212)  评论(0)    收藏  举报

导航