问题描述:
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;
}
|