C# gdal 将geojson批量导入到 gdb(FileGeodatabase)文件中
需求
需要将地块的geojson数据导入到gdb文件中
思路
为了方便后期使用和集成,于是采用C#(或者java)的方式,利用gdal创建gdb文件并将geojson数据导入其中
环境
win10、VS2015
实现过程
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/xlp789/article/details/128363235
1)、安装gdal-300-1900-x64-filegdb.msi文件,安装后找到对应文件夹,将文件复制到开发工程的bin\Debug目录中

2)、将release-1900-x64-gdal-3-0-4-mapserver-7-4-3\bin\gdal\csharp下的8个dll拷贝到开发工程的bin\Debug目录中

3)、将release-1900-x64-gdal-3-0-4-mapserver-7-4-3\bin\下的文件拷贝到开发工程的bin\Debug目录中

4)、设置工程的目标平台为X64,如下图所示:

5)、添加引用 包含四个dll:gdal_csharp.dll、gdalconst_csharp.dll 、ogr_csharp.dll 、osr_csharp.dll ,如下图所示

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

7)、初始化gdal开发环境
//为了支持中文路径 Gdal.SetConfigOption("SHAPE_ENCODING", ""); //解决字段乱码问题 Gdal.AllRegister(); Ogr.RegisterAll(); OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
8)、geojson数据检查方法1
//json数据检查 特定格式 public string GeoJsonCheck(string filepath) { try { System.IO.FileInfo fileInfo = fileInfo = new System.IO.FileInfo(filepath); double fileSize = System.Math.Ceiling(fileInfo.Length / 1024.0/1024); if (fileSize > 25) { return "文件过大("+ fileSize + " MB),不能大于 25MB"; } string json = string.Empty; using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs, Encoding.UTF8)) { json = sr.ReadToEnd().ToString(); JObject jo = (JObject)JsonConvert.DeserializeObject(json); JArray features = (JArray)jo["features"]; for (int i = 0; i < features.Count; i++) { JObject fea = (JObject)features[i]; JArray coordinates = (JArray)fea["geometry"]["coordinates"]; for (int a = 0; a < coordinates.Count; a++) { bool isError = false; JArray ring1 = (JArray)coordinates[a]; for (int b = 0; b < ring1.Count; b++) { if (isError) break; JArray ring2 = (JArray)ring1[b]; for (int c = 0; c < ring2.Count; c++) { JArray ring3 = (JArray)ring2[c]; if (ring3.Count > 2) { coordinates.RemoveAt(a); a--; isError = true; break; } } } } } // 将文件指针重置到开头 fs.Seek(0, SeekOrigin.Begin); // 写入修改后的内容 byte[] modifiedBuffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jo)); fs.Write(modifiedBuffer, 0, modifiedBuffer.Length); // 如果新内容比原内容短,需要截断文件 fs.SetLength(modifiedBuffer.Length); } } return ""; } catch (Exception ex) { return ex.Message; } }
9)、geojson数据检查,方法2
//json数据检查,使用geojson.dll public string GeoJsonCheck(string filepath) { string result = ""; string json = string.Empty; using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs, Encoding.UTF8)) { try { json = sr.ReadToEnd().ToString(); GeoJson data = JsonConvert.DeserializeObject<GeoJson>(json); } catch (Exception ex) { result="格式错误"; } } } return result; }
10、导入多个geojson文件到gdb文件中
//导入多个geojson文件到gdb中 public string importGeojsonsToGdb(List<string> inputGeojsonfiles, string gdbFilePath) { string result = ""; try { // gdb文件存在就删除 if (Directory.Exists(gdbFilePath)) { // 删除目录及其内容 Directory.Delete(gdbFilePath, true); } // 创建或打开GDB文件 string driverName = "FileGDB"; OSGeo.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[0], 0); if (firstInputDataSource == null) { result = "读取失败: " + inputGeojsonfiles[0]; return result; } Layer firstInputLayer = firstInputDataSource.GetLayerByIndex(0); if (firstInputLayer == null) { result ="获取图层失败: " + inputGeojsonfiles[0]; return result; } // 合并所有输入 Shapefile 的要素 foreach (string inputShapefile in inputGeojsonfiles) { string fileName = Path.GetFileNameWithoutExtension(inputShapefile); // 在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(); OSGeo.OGR.Feature inputFeature; while ((inputFeature = inputLayer.GetNextFeature()) != null) { OSGeo.OGR.Feature outputFeature = new OSGeo.OGR.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.Dispose(); } // 释放资源 firstInputDataSource.Dispose(); gdbDataSource.Dispose(); } catch (Exception ex) { result = ex.Message; } return result; }
11、导入多个geojson并合并(坐标系、类型及属性字段相同)到gdb文件中
//导入合并多个geojson文件到gdb中 public string importGeojsonsAndMergeToGdb(List<string> inputGeojsonfiles, string gdbFilePath, string newLayerName) { string result = ""; try { // gdb文件存在就删除 if (Directory.Exists(gdbFilePath)) { // 删除目录及其内容 Directory.Delete(gdbFilePath, true); } // 创建或打开GDB文件 string driverName = "FileGDB"; OSGeo.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[0], 0); if (firstInputDataSource == null) { result = "读取失败: " + inputGeojsonfiles[0]; return result; } Layer firstInputLayer = firstInputDataSource.GetLayerByIndex(0); if (firstInputLayer == null) { result = "获取图层失败: " + inputGeojsonfiles[0]; return result; } // 在GDB中创建相同的图层 Layer gdbLayer = gdbDataSource.CreateLayer(newLayerName, 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; } } // 合并所有输入 Shapefile 的要素 foreach (string inputShapefile in inputGeojsonfiles) { 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(); OSGeo.OGR.Feature inputFeature; while ((inputFeature = inputLayer.GetNextFeature()) != null) { OSGeo.OGR.Feature outputFeature = new OSGeo.OGR.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.Dispose(); } // 释放资源 firstInputDataSource.Dispose(); gdbDataSource.Dispose(); } catch (Exception ex) { result = ex.Message; } return result; }
12、界面截图如下:

posted on 2025-03-15 18:35 Geography爱好者 阅读(130) 评论(0) 收藏 举报
浙公网安备 33010602011771号