.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.");
    }
}
相关推荐
△曉風殘月〆5 小时前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm
逐·風7 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
m0_6569747410 小时前
C#中的集合类及其使用
开发语言·c#
九鼎科技-Leo10 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo12 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发12 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
小乖兽技术12 小时前
C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)
c++·c#·交互·ipc
幼儿园园霸柒柒13 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
平凡シンプル15 小时前
C# EF 使用
c#
丁德双16 小时前
winform 加载 office excel 插入QRCode图片如何设定位置
c#·excel