.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.");
    }
}
相关推荐
dot.Net安全矩阵1 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
zls3653651 小时前
.NET开源实时应用监控系统:WatchDog
.net
djk88881 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
ZwaterZ1 小时前
el-table-column自动生成序号&&在序号前插入图标
前端·javascript·c#·vue
SRC_BLUE_174 小时前
SQLI LABS | Less-55 GET-Challenge-Union-14 Queries Allowed-Variation 2
oracle·c#·less
yngsqq4 小时前
037集——JoinEntities连接多段线polyline和圆弧arc(CAD—C#二次开发入门)
开发语言·c#·swift
Zԅ(¯ㅂ¯ԅ)4 小时前
C#桌面应用制作计算器进阶版01
开发语言·c#
hccee6 小时前
C#之异步编程
c#
麻花20136 小时前
C#之WPF的C1FlexGrid空间的行加载事件和列事件变更处理动态加载的枚举值
开发语言·c#·wpf
Crazy Struggle6 小时前
功能齐全的 WPF 自定义控件资源库(收藏版)
.net·wpf·ui控件库