继“CP936”也失效之后重新自定义方法解决GDAL读取SHP乱码问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/funkstill/article/details/88327074

问题描述:

    emmmm,水平太菜,这个问题看起来比较玄幻。之前默认

OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");

的时候,完全乱码。之后采取设置(详见C#借助GDAL实现对shp属性按字段读取,并解决乱码问题

OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "CP936");

暂时解决了乱码问题。但是玄幻就玄幻在做完数据入库后,这个解决方案又挂了。。。。。最后参考网上文档采取了一种稍微复杂点的方案解决:

    1.添加引用

using OSGeo.OGR;
using System.Runtime.InteropServices;

    2.在类中加入(注意gdal版本号)

//解决shp属性乱码问题
[DllImport("gdal111.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]
public extern static System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int i); 

    3.注册驱动

Gdal.AllRegister();
Ogr.RegisterAll();
            
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "GB18030");

    4.读取

/// <summary>
/// 获取shp信息统计存入结构体Item
/// </summary>
/// <param name="shpFilePath">shp路径</param>
/// <param name="item">存储结构体</param>
/// <returns>信息结构体</returns>
public static Item getShpInfo(String shpFilePath,String timeid) 
{
    
    OSGeo.OGR.Driver driver = Ogr.GetDriverByName("ESRI Shapefile");
    DataSource ds = null;
    Layer layer = null;
    Item item = new Item();
    try
    {
        ds = Ogr.Open(shpFilePath, 0);
        layer = ds.GetLayerByIndex(0);
        
        //int count = (int)layer.GetFeatureCount(0);
        item.number = (int)layer.GetFeatureCount(0);//当前shp中总元素数
        /*..*/
        
        Feature fe = layer.GetNextFeature();
        int flagCount = 0;//用于标记只需提取一次的字段
        #region 遍历所有要素
        while (fe != null)
        {
            
            if(flagCount==0)//XZQDM和XMC提取一次即可
            {
                flagCount++;
                item.regionid = getRightStr(fe,2);//行政区代码
                item.name = getRightStr(fe, 3);//区县名称

            }
            /**/
            fe = layer.GetNextFeature();
        }
        #endregion

        
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        if (layer != null)
        {
            layer.Dispose();
        }
        if (ds != null)
        {
            ds.Dispose();
        }
        driver.Dispose();
    }
    return item;
}

    5.自定义的方法

/// <summary>
/// 解决中文乱码问题
/// </summary>
/// <param name="fe">当前要素</param>
/// <param name="index">字段</param>
/// <returns></returns>
public static String getRightStr(Feature fe,int index)
{
    IntPtr pchar = OGR_F_GetFieldAsString(OSGeo.OGR.Feature.getCPtr(fe), index);
    String str = Marshal.PtrToStringAnsi(pchar);
    return str;
}

猜你喜欢

转载自blog.csdn.net/funkstill/article/details/88327074