.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.");
    }
}
相关推荐
Zhen (Evan) Wang1 小时前
ABP-Book Store Application中文讲解 - Part 2: The Book List Page
c#
小乖兽技术3 小时前
在 .NET 8 开发的WinForms 程序中展示程序版本号的几种方式
开发语言·c#·.net
TheWindofFate3 小时前
C# 基础 try-catch代码块
c#·try-catch
TIF星空7 小时前
【使用 C# 获取 USB 设备信息及进行通信】
开发语言·经验分享·笔记·学习·microsoft·c#
csdn_aspnet9 小时前
如何在 C# 中自定义 Datagridview 标题
c#·winform·datagridview
津津有味道9 小时前
MIFARE DESFire Light 卡C#读写更改卡片密钥源码
c#·light·desfire·ev2
炯哈哈12 小时前
【上位机——WPF】Window标签常用属性
开发语言·c#·wpf·上位机
瓜皮弟子头很铁16 小时前
.net 公共变量 线程安全
.net
江沉晚呤时18 小时前
C# 实现雪花算法(Snowflake Algorithm)详解与应用
c#·.net
GIS思维20 小时前
ArcGIS Pro地块图斑顺序编号(手绘线顺序快速编号)-004
gis·arcgispro·图斑编号