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

1 篇文章 0 订阅

问题描述:

    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;
}

 

解决GDAL读取Shapefile文件后输出中文乱码问题,可以通过设置合适的编码来处理。下面是一个示例代码,演示如何使用GDAL读取Shapefile文件并正确处理中文字符: ```python from osgeo import ogr # 打开Shapefile dataset = ogr.Open('input_shapefile.shp', 0) layer = dataset.GetLayer() # 获取属性表编码 layer_encoding = layer.GetLayerDefn().GetFieldDefn(0).GetEncoding() # 设置输出编码 output_encoding = 'utf-8' # 遍历要素并输出属性值 for feature in layer: for i in range(feature.GetFieldCount()): field_value = feature.GetField(i) # 解码属性值为Unicode字符串 field_value_unicode = field_value.decode(layer_encoding) # 编码为指定输出编码的字符串 field_value_encoded = field_value_unicode.encode(output_encoding) # 输出属性值 print(field_value_encoded) # 关闭数据集 dataset = None ``` 在上述代码中,我们首先通过`GetLayerDefn()`方法获取属性表的编码,并将其保存在`layer_encoding`变量中。然后,我们将输出编码设置为`utf-8`,可以根据需要修改为其他编码。接下来,我们遍历要素并使用`decode()`方法属性值解码为Unicode字符串,然后使用`encode()`方法将其编码为指定的输出编码字符串。最后,我们使用`print()`语句输出属性值。 请将`input_shapefile.shp`替换为您要读取Shapefile文件路径。如果您的Shapefile文件使用了其他编码,请在`layer.GetLayerDefn().GetFieldDefn(0).GetEncoding()`中指定正确的编码。 希望这可以解决您的问题!如果您有任何进一步的疑问,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值