C# GDAL编码问题2——读取中文属性
前面解决了打开mdb乱码的问题,但又出现读取中文属性乱码的问题,不光是mdb,还有gdb,shp都存在此问题,究其原因依然是封装C#版时的bug造成的,直接说解决方案:
原版有个Utf8BytesToString方法,直接调用PtrToStringAnsi获取字节长度,没有考虑不同编码字节长度不同的问题。
修改前:

修改后:

internal static string Utf8BytesToString(IntPtr pNativeData)
{
string result;
if (pNativeData == IntPtr.Zero)
{
result = null;
}
else
{
int num = 0;
byte[] array = new byte[0];
do
{
num++;
Array.Resize<byte>(ref array, num);
Marshal.Copy(pNativeData, array, 0, num);
}
while (array[num - 1] != 0);
if (1 == num)
{
result = "";
}
else
{
Array.Resize<byte>(ref array, num - 1);
result = Encoding.UTF8.GetString(array);
}
}
return result;
}
同样的问题在于SWIGStringHelper类中CreateString方法。
修改前:

修改后:

protected class SWIGStringHelper
{
[DllImport("ogr_wrap")]
public static extern void SWIGRegisterStringCallback_Ogr(OgrPINVOKE.SWIGStringHelper.SWIGStringDelegate stringDelegate);
private static string CreateString(IntPtr pNativeData)
{
string result;
if (pNativeData == IntPtr.Zero)
{
result = null;
}
else
{
int num = 0;
byte[] array = new byte[0];
do
{
num++;
Array.Resize<byte>(ref array, num);
Marshal.Copy(pNativeData, array, 0, num);
}
while (array[num - 1] != 0);
if (1 == num)
{
result = "";
}
else
{
Array.Resize<byte>(ref array, num - 1);
result = Encoding.UTF8.GetString(array);
}
}
return result;
}
static SWIGStringHelper()
{
OgrPINVOKE.SWIGStringHelper.SWIGRegisterStringCallback_Ogr(OgrPINVOKE.SWIGStringHelper.stringDelegate);
}
private static OgrPINVOKE.SWIGStringHelper.SWIGStringDelegate stringDelegate = new OgrPINVOKE.SWIGStringHelper.SWIGStringDelegate(OgrPINVOKE.SWIGStringHelper.CreateString);
public delegate string SWIGStringDelegate(IntPtr pNativeData);
}
但这样的修改还是只能处理gdb和shp问题,mdb的还是不行!得调用底层GDAL的API才行。
选来一个扩展方法:
/// <summary>
/// 读取要素字段值
/// </summary>
/// <param name="handle"></param>
/// <param name="index"></param>
/// <returns></returns>
[DllImport("gdal204.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
public static extern System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int index);
/// <summary>
/// 读取要素字段值
/// </summary>
/// <param name="feature"></param>
/// <param name="index"></param>
/// <returns></returns>
public static string GetFieldAsStringEx(this Feature feature, int index)
{
IntPtr pStr = OGR_F_GetFieldAsString(Feature.getCPtr(feature), index);
return Marshal.PtrToStringAnsi(pStr);
}
public static string GetFieldAsStringEx(this Feature feature, string name)
{
var index = feature.GetFieldIndex(name);
if (index >= 0)
{
return (GetFieldAsStringEx(feature, index));
}
throw new IndexOutOfRangeException();
}
再使用扩展方法来读取就好了。
Layer layer = mdbDataSource.GetLayerByIndex(1);
FeatureDefn featureDefn = layer.GetLayerDefn();
int iFieldCount = featureDefn.GetFieldCount();
Feature feature = null;
while ((feature = layer.GetNextFeature()) != null)
{
string s = "";
for (int j = 0; j < iFieldCount; j++)
{
s += feature.GetFieldAsStringEx(j) + "\t\t\t";
}
Console.WriteLine(s);
}
作者:我也是个傻瓜
出处:http://www.cnblogs.com/liweis/
签名:成熟是一种明亮而不刺眼的光辉。

浙公网安备 33010602011771号