java gdal 将geojson批量导入到 gdb(FileGeodatabase)文件中
需求
需要将地块的geojson数据导入到gdb文件中
思路
为了方便后期使用和集成,于是采用java(或者C#)的方式,利用gdal创建gdb文件并将geojson数据导入其中
环境
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拷贝到jdk的bin目录下,如下图所示

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放到jdk的bin目录下,参考2->3)节点。
或者设置gdalalljni.dll的环境变量
-
打开 系统环境变量设置
-
找到
PATH变量,点击编辑 -
添加一行:
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) 收藏 举报
浙公网安备 33010602011771号