C#编译版GDAL读取矢量数据导入PG数据库中文字段乱码解决方案
程序员文章站
2022-03-20 13:30:50
...
最近在研究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);
}
}
上一篇: fckeditor2.6如何取值?
下一篇: GDAL读取查询shp数据