gdal调用capi处理乱码问题(c#)
gdal在处理SHP文件的时候总会遇到中文字段和中文属性值的乱码问题、获取postgresql中的中文表名的时候、mdb中的中文表名,造成这些的原因一些是由于编码问题,还有是gdal上层封装的bug,在公司大佬的提点下获取到了解决方案,掉用c api,那么首先得找到API的名称:
https://gdal.org/python/index.html
先设置环境变量
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
然后写扩展方法
public static class GetRightString{[DllImport("gdal300.dll", EntryPoint = "OGR_F_GetFieldAsString", CallingConvention = CallingConvention.Cdecl)]public extern static System.IntPtr OGR_F_GetFieldAsString(HandleRef handle, int i);[DllImport("gdal300.dll", EntryPoint = "OGR_F_GetFieldAsBinary", CallingConvention = CallingConvention.Cdecl)]public extern static System.IntPtr OGR_F_GetFieldAsBinary(HandleRef handle, int index, out int byteCount);[DllImport("gdal300.dll", EntryPoint = "CPLStrnlen", CallingConvention = CallingConvention.Cdecl)]public extern static uint CPLStrnlen(IntPtr handle, uint nMaxLen);public static String getRightStr(Feature fe, int index, string workspaceType){if (workspaceType == "GDB"){int byteCount = 0;IntPtr pIntPtr = OGR_F_GetFieldAsBinary(OSGeo.OGR.Feature.getCPtr(fe), index, out byteCount);byte[] byteArray = new byte[byteCount];Marshal.Copy(pIntPtr, byteArray, 0, byteCount);//Console.WriteLine(byteCount);string str = System.Text.Encoding.UTF8.GetString(byteArray);return str;}else if (workspaceType == "SHP"){IntPtr pchar = OGR_F_GetFieldAsString(OSGeo.OGR.Feature.getCPtr(fe), index);int length = (int)CPLStrnlen(pchar, uint.MaxValue);byte[] strbuf = new byte[length];Marshal.Copy(pchar, strbuf, 0, length);string utf8String = System.Text.Encoding.UTF8.GetString(strbuf);return utf8String;}else{return fe.GetFieldAsString(index);}}[DllImport("gdal300.dll", EntryPoint = "OGR_F_SetFieldString", CallingConvention = CallingConvention.Cdecl)]public extern static void OGR_F_SetFieldString(HandleRef handle, int index, string val);public static void setFieldString(Feature fe, int index, string val, string workspaceType){if (workspaceType == "SHP"){OGR_F_SetFieldString(OSGeo.OGR.Feature.getCPtr(fe), index, val);}else{fe.SetField(index, val);}}[DllImport("gdal300.dll", EntryPoint = "OGR_Fld_GetNameRef", CallingConvention = CallingConvention.Cdecl)]public extern static System.IntPtr OGR_Fld_GetNameRef(HandleRef handle);[DllImport("gdal300.dll", EntryPoint = "OGR_DS_GetLayer", CallingConvention = CallingConvention.Cdecl)]public extern static System.IntPtr OGR_DS_GetLayer(IntPtr handle, int nIdx);[DllImport("gdal300.dll", EntryPoint = "OGR_L_GetName", CallingConvention = CallingConvention.Cdecl)]public extern static System.IntPtr OGR_L_GetName(HandleRef handle);public static string GetFieldNameEx(FieldDefn layer){IntPtr pName = OGR_Fld_GetNameRef(OSGeo.OGR.FieldDefn.getCPtr(layer));int length = (int)CPLStrnlen(pName, uint.MaxValue);byte[] strbuf = new byte[length];Marshal.Copy(pName, strbuf, 0, length);string utf8String = System.Text.Encoding.UTF8.GetString(strbuf);return utf8String;}public static string GetNameEx(Layer layer){IntPtr pName = OGR_L_GetName(OSGeo.OGR.Layer.getCPtr(layer));int length = (int)CPLStrnlen(pName, uint.MaxValue);byte[] strbuf = new byte[length];Marshal.Copy(pName, strbuf, 0, length);string utf8String = System.Text.Encoding.UTF8.GetString(strbuf);return utf8String;}}
调用方法:
shp创建中文字段乱码:
FeatureDefn pgDef = lyPG.GetLayerDefn();int iFieldCount = pgDef.GetFieldCount();FieldDefn pgFieldDef = null;FieldDefn shpFdefn = null;List<string> lstField = new List<string>();string fieldName = "";for (int j = 0; j < iFieldCount; j++){pgFieldDef = pgDef.GetFieldDefn(j);fieldName = pgFieldDef.GetName();fieldName = GetRightString.GetFieldNameEx(pgFieldDef);shpFdefn = new FieldDefn(fieldName, pgFieldDef.GetFieldType());shpFdefn.SetName(fieldName);lstField.Add("\"" + fieldName.ToUpper() + "\"");shpFdefn.SetWidth(pgFieldDef.GetWidth());shpFdefn.SetPrecision(pgFieldDef.GetPrecision());lySHP.CreateField(shpFdefn, 1);}
获取图层名乱码问题:
lyPG = pgDataSource.GetLayerByIndex(l);
layerName = MyDataConvertTool.DataConvertUtils.GetRightString.GetNameEx(lyPG);
获取中文字段值:
sVal = GetRightString.getRightStr(fromFeature, cgFieldIndex, "SHP");
shp属性赋值乱码问题:
GetRightString.setFieldString(toFeature, tagFieldIndex, sVal, "SHP");
参考:
C# GDAL编码问题3——读取中文图层
gdal调用capi处理乱码问题(c#)相关推荐
- 【Lua进阶系列】实例lua调用capi
[Lua进阶系列]实例lua调用capi 大家好,我是Lampard~~ 欢迎来到Lua进阶系列的博客 首先祝大家2021新年 ...
- 基于C#的GDAL调用之根据Geotif生成相应tfw
基于C#的GDAL调用之根据Geotif生成相应tfw 有时候为了方便查看Geotif影像的六参数信息,经常会将其六参数信息写出,生成相应的tfw文件.这里利用C#调用GDAL,批量生成指定Geoti ...
- utf-8编码用于asp出现乱码的问题--从数据库调用的是乱码
用utf-8编码的网站,问题还真多,开始把 CODEPAGE="936" 改成 CODEPAGE="65001" 把charset=gb2312改成 chars ...
- 外部程序调用四五打印乱码
外部程序调用显示出的内容乱码: 程序使用的为gb2312编码再base64编码,用utf8转base64则为乱码 0,优速快递,1,单位名称,单位简称,开户银行,帐号,国家,省份,地市,区镇,联系地址 ...
- 解决C++调用Python中文乱码
C++调用Python,包括参数传递及返回值的处理的教程都很多.但是对于中文字符作为参数传递时,会遇到编码问题而乱码甚至崩溃.经过搜集资料,终于解决乱码问题,特记录在此: 1.参数传递一般采用PyOb ...
- SpringMVC调用接口一直乱码
看到网上的各种解决方案,也慢慢的尝试 1.比如: @RequestMapping(value="/getgdarticle",produces="application/ ...
- linux调用odbc接口乱码,linux中pypyodbc读取GB编码mdb中文乱码解决办法
当前1.3.3版本的pypyodbc在linux系统上面已经可以读取有中文字符的mdb文件,不再出现异常,但是读取的中文字符却全是乱码. 下面是根据一些现象的合理推论: mdb文件来自于windows ...
- Linux下 Python通过ctypes调用cAPI (一)
c_long和c_int是一种类型. cdll加载使用标准cdecl调用约定导出函数的库 windll使用stdcall调用约定调用函数 oledll也使用stdcall调用约定 在linux下通过两 ...
- python调用graphviz中文乱码_Python-Graphviz
一.graphviz安装及配置 二.graphviz的使用 graphviz 有两种图,一种是无向图 graph ,边用 -- 连接:一种是有向图 digraph ,边用 -> 连接 官网API ...
最新文章
- JavaScript 开发者数量暴涨、C# 超越 PHP,揭晓全球开发最新趋势!
- NLP(自然语言处理)详细笔记
- 基于SQL on Hadoop的数据仓库技术
- 【新星计划】MATLAB-字符串处理
- 【Protocol Buffer】Protocol Buffer入门教程(五):repeated限定修饰符
- TRUNCATE vs DELETE命令
- CentOS 7.7(1908)发布
- 站在“巨人”的肩膀上运维
- 【转】阿里去IOE运动
- cdr软件百度百科_什么是CDR软件?
- 工作流的大致开发流程
- 百分比布局得应用 —— 模仿京东移动端首页
- ubuntu16.04安装搜狗拼音输入法
- clickhouse 入门介绍和预演
- 中国第一代***骄傲
- 《极客与团队》一HRT实战
- c语言逗号分隔字符串,[数字用逗号隔开怎么读]看到一个数字中间有逗号
- C++ 使用chrono库准确统计代码运行时间
- 微信公众号获取的实时坐标和高德地图坐标系的转换
- yum源本地配置和网络源配置——超级完整详细
热门文章
- numpy函数:arange(),reshape()用法,
- 解决win10下高分屏的字体显示模糊问题
- 余弦相似度(Cosine Similarity)
- android 电话回音消除,android系统通话中回声消除的实现.pdf
- python ui框架哪个最好用_Python UI开发最常用到的库
- 麓言科技怎么成为广告设计师
- 数学----勾股定理证明
- [转]WIN MOBILE UI开发入门
- 给定数字0-9各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意0不能做首位)
- LINK 2001 找不到__iob_func, 找不到__fprintf