.NET C# 使用GDAL将mdb转换gdb数据

.NET C# 使用GDAL将mdb转换gdb数据

目录

  • [.NET C# 使用GDAL将mdb转换gdb数据](# 使用GDAL将mdb转换gdb数据)
    • [1 环境](#1 环境)
    • [2 Nuget](#2 Nuget)
    • [3 Code](#3 Code)

1 环境

VisualStudio2022 + .NET6 + GDAL 3.8.5

2 Nuget

3 Code

FeatureExtension.cs

csharp 复制代码
public static class FeatureExtension
{
    [DllImport("gdal.dll", EntryPoint = "OGR_F_GetFieldAsBinary", CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr OGR_F_GetFieldAsBinary(HandleRef handle, int index, out int byteCount);
    [DllImport("gdal.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr OGR_F_GetFieldAsString(HandleRef handle, int i);
    [DllImport("gdal.dll", EntryPoint = "CPLStrnlen", CallingConvention = CallingConvention.Cdecl)]
    public extern static uint CPLStrnlen(IntPtr handle, uint nMaxLen);

    public static byte[] GetFieldAsBinary(this Feature feature, int index, FeatureDatastoreType datastoreType)
    {
        if (datastoreType == FeatureDatastoreType.GDB)
        {
            int byteCount = 0;
            IntPtr pIntPtr = OGR_F_GetFieldAsBinary(Feature.getCPtr(feature), index, out byteCount);
            byte[] byteArray = new byte[byteCount];
            Marshal.Copy(pIntPtr, byteArray, 0, byteCount);
            return byteArray;
        }
        else
        {
            IntPtr pchar = OGR_F_GetFieldAsString(Feature.getCPtr(feature), index);
            int length = (int)CPLStrnlen(pchar, uint.MaxValue);
            byte[] byteArray = new byte[length];
            Marshal.Copy(pchar, byteArray, 0, length);
            return byteArray;
        }
    }
    public static byte[] GetFieldAsBinary(this Feature feature, string fieldName, FeatureDatastoreType datastoreType)
    {
        int index = feature.GetFieldIndex(fieldName);
        if (datastoreType == FeatureDatastoreType.GDB)
        {
            int byteCount = 0;
            IntPtr pIntPtr = OGR_F_GetFieldAsBinary(Feature.getCPtr(feature), index, out byteCount);
            byte[] byteArray = new byte[byteCount];
            Marshal.Copy(pIntPtr, byteArray, 0, byteCount);
            return byteArray;
        }
        else
        {
            IntPtr pchar = OGR_F_GetFieldAsString(Feature.getCPtr(feature), index);
            int length = (int)CPLStrnlen(pchar, uint.MaxValue);
            byte[] byteArray = new byte[length];
            Marshal.Copy(pchar, byteArray, 0, length);
            return byteArray;
        }
    }
}

FeatureDatastoreType.cs

csharp 复制代码
public enum FeatureDatastoreType
{
    Other,
    GDB
}

MDB2GDB.cs

csharp 复制代码
public class MDB2GDB
{
    public void Convert(string mdbFilePath, string gdbFilePath)
    {
        // 注册所有驱动
        GdalConfiguration.ConfigureGdal();
        GdalConfiguration.ConfigureOgr();

        // 注册编码提供程序以支持GBK编码
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        // 打开MDB数据源
        var mdbDriver = Ogr.GetDriverByName("PGeo");
        if (mdbDriver == null)
        {
            Console.WriteLine("MDB driver is not available.");
            return;
        }
        DataSource mdbDataSource = null;
        try
        {
            mdbDataSource = mdbDriver.Open(mdbFilePath, 0);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Failed to open MDB file.");
            return;
        }

        // 创建GDB数据源
        Driver gdbDriver = Ogr.GetDriverByName("OpenFileGDB");
        if (gdbDriver == null)
        {
            Console.WriteLine("OpenFileGDB driver is not available.");
            return;
        }

        DataSource gdbDataSource = null;
        try
        {
            gdbDataSource = gdbDriver.CreateDataSource(gdbFilePath, null);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Failed to create GDB file.");
            return;
        }

        // 遍历MDB数据源中的所有图层并复制到GDB数据源
        for (int i = 0; i < mdbDataSource.GetLayerCount(); i++)
        {
            Layer mdbLayer = mdbDataSource.GetLayerByIndex(i);
            string lyrName = mdbLayer.GetName();
            Layer gdbLayer = gdbDataSource.CreateLayer(lyrName, mdbLayer.GetSpatialRef(), mdbLayer.GetGeomType(), null);
            Console.WriteLine($"Source Layer: {lyrName}");
            // 复制字段定义
            FeatureDefn mdbFeatureDefn = mdbLayer.GetLayerDefn();
            for (int j = 0; j < mdbFeatureDefn.GetFieldCount(); j++)
            {
                FieldDefn fieldDefn = mdbFeatureDefn.GetFieldDefn(j);
                string fieldName = fieldDefn.GetName();

                Console.WriteLine($"Source Field: {fieldDefn.GetName()} - Right Field: {fieldName}");
                gdbLayer.CreateField(fieldDefn, 1);
            }

            mdbLayer.ResetReading();
            // 复制要素
            Feature mdbFeature;
            while ((mdbFeature = mdbLayer.GetNextFeature()) != null)
            {
                Feature gdbFeature = new Feature(gdbLayer.GetLayerDefn());
                gdbFeature.SetFrom(mdbFeature, 1);

                // 显式设置字段的字符编码,这里为解决MDB数据中的中文使用GBK编码导致的中文乱码问题
                for (int j = 0; j < gdbFeature.GetFieldCount(); j++)
                {
                    FieldType fieldType = gdbFeature.GetFieldDefnRef(j).GetFieldType();
                    if (fieldType == FieldType.OFTString || fieldType == FieldType.OFTWideString)
                    {
                        byte[] bytes = gdbFeature.GetFieldAsBinary(j, FeatureDatastoreType.Other);
                        string fieldValue = Encoding.GetEncoding("GBK").GetString(bytes);
                        gdbFeature.SetField(j, fieldValue);
                    }
                }
                //如果MDB数据编码使用的utf8则不需要上面这段代码

                gdbLayer.CreateFeature(gdbFeature);
                mdbFeature.Dispose();
                gdbFeature.Dispose();
            }
        }

        // 释放资源
        mdbDataSource.Dispose();
        gdbDataSource.Dispose();

        Console.WriteLine("Conversion completed successfully.");
    }
}
相关推荐
向宇it4 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
数据的世界014 小时前
.NET开发人员学习书籍推荐
学习·.net
向宇it5 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
paixiaoxin6 小时前
CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究
人工智能·深度学习·机器学习·生成对抗网络·计算机视觉·ocr·.net
坐井观老天10 小时前
在C#中使用资源保存图像和文本和其他数据并在运行时加载
开发语言·c#
supermapsupport12 小时前
iClent3D for Cesium 实现无人机巡检飞行效果
gis·cesium·supermap·webgis
pchmi12 小时前
C# OpenCV机器视觉:模板匹配
opencv·c#·机器视觉
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭14 小时前
C#都可以找哪些工作?
开发语言·c#
19004314 小时前
.NET重点
.net
m0_6632340114 小时前
在 .NET 5.0 运行 .NET 8.0 教程:使用 ASP.NET Core 创建 Web API
前端·asp.net·.net