欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#编译版GDAL读取矢量数据导入PG数据库中文字段乱码解决方案

程序员文章站 2022-03-20 13:30:50
...

最近在研究GDAL,在尝试将矢量数据导入到pg中时出现了中文字段乱码的问题。乱码类似于下图:

C#编译版GDAL读取矢量数据导入PG数据库中文字段乱码解决方案

百度了一下,大部分都是说要设置

Gdal.SetConfigOption("SHAPE_ENCODING", string.Empty);

但是我设置完之后完全没用,甚至还不如之前,一个汉字都没了全变成乱码了。我有跟断点发现我从源数据里读出来的数据就已经是乱码了,感觉有点拉闸。最后在一个群友的指导下,通过DllImport的方式引用原本的gdal204.dll(不同的GDAL版本数字不同)文件,使用里面的字段读取函数来获取字段的值。虽然一开始也是乱码,但是上面的编码设置终于起作用了,加上后终于正常了。个人推测是GDAL的C#编译版在读取中文字段的时候有问题,但是具体什么原因我也没搞明白。具体代码如下。

[DllImport("gdal204.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr OGR_F_GetFieldAsString(HandleRef handle, int fieldIdx);

        private static void ImportVectorData2PG()
        {
            Ogr.RegisterAll();

            // 支持中文路径
            // Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");

            // 使字段支持中文
            Gdal.SetConfigOption("SHAPE_ENCODING", string.Empty);

            // 读取矢量文件信息
            string sourceVector = @"D:\DTLFolder\ogrtest.shp";
            DataSource srcVectorDs = Ogr.Open(sourceVector, 0);

            // 只读取第一个图层
            Layer srcVectorLy = srcVectorDs.GetLayerByIndex(0);
            FeatureDefn srcVectorDefn = srcVectorLy.GetLayerDefn();
            string layerName = srcVectorLy.GetName();
            SpatialReference spatialReference = srcVectorLy.GetSpatialRef();
            wkbGeometryType wkbGeometryType = srcVectorLy.GetGeomType();

            // 读取PG库信息
            string connStr = "PG:dbname=yanshi host=localhost port=5432 user=postgres password=postgres";
            OSGeo.OGR.Driver drv = Ogr.GetDriverByName("PostgreSQL");
            DataSource dataSource = drv.Open(connStr, 1); // 0是只读?
            Layer layer = dataSource.GetLayerByName(layerName);

            // 没有同名图层则创建同结构新图层
            if (layer == null)
            {
                layer = dataSource.CreateLayer(layerName, spatialReference, wkbGeometryType, null);
                int fieldCount = srcVectorDefn.GetFieldCount();
                for (int i = 0; i < fieldCount; i++)
                {
                    FieldDefn fieldDefn = srcVectorDefn.GetFieldDefn(i);
                    layer.CreateField(fieldDefn, 1);
                }

                int geoFieldCount = srcVectorDefn.GetGeomFieldCount();
                for (int i = 0; i < geoFieldCount; i++)
                {
                    GeomFieldDefn geomFieldDefn = srcVectorDefn.GetGeomFieldDefn(i);
                    layer.CreateGeomField(geomFieldDefn, 1);
                }
            }

            // 循环赋值创建
            Feature feature = null;
            while ((feature = srcVectorLy.GetNextFeature()) != null)
            {
                FeatureDefn featureDefn = layer.GetLayerDefn();
                Feature newFeature = new Feature(featureDefn);
                for (int i = 0; i < srcVectorDefn.GetFieldCount(); i++)
                {
                    FieldDefn oDefn = srcVectorDefn.GetFieldDefn(i);
                    FieldType type = oDefn.GetFieldType();
                    switch (type)
                    {
                        case FieldType.OFTInteger:
                            newFeature.SetField(i, feature.GetFieldAsInteger(i));
                            break;
                        case FieldType.OFTReal:
                            newFeature.SetField(i, feature.GetFieldAsDouble(i));
                            break;
                        case FieldType.OFTString:
                            string val = Marshal.PtrToStringAnsi(OGR_F_GetFieldAsString(Feature.getCPtr(feature), i));
                            newFeature.SetField(i, val);
                            break;
                        default:
                            newFeature.SetField(i, feature.GetFieldAsString(i));
                            break;
                    }
                }

                for (int i = 0; i < srcVectorDefn.GetGeomFieldCount(); i++)
                {
                    Geometry geometry = feature.GetGeomFieldRef(i);
                    newFeature.SetGeometry(geometry);
                }

                layer.CreateFeature(newFeature);
            }
        }

 

相关标签: GDAL