zoukankan      html  css  js  c++  java
  • 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) + "			";
        }
        Console.WriteLine(s);
    }
    
  • 相关阅读:
    多媒体基础知识之PCM数据
    FFmpeg在Linux下编译使用
    AndroidStudio 中使用FFMPEG
    Android 音频播放分析笔记
    【Linux 命令】- more和less
    【Linux】- 简明Vim练习攻略
    【Linux】- 对find,xargs,grep和管道的一些理解
    【Linux 命令】- find 命令
    【Linux 命令】- tar 命令
    【Linux】- CentOS7 下 安装 supervisor
  • 原文地址:https://www.cnblogs.com/liweis/p/13747862.html
Copyright © 2011-2022 走看看