GDAL C#读取shp中文属性值乱码问题
GDAL的C#版本读取shp中,如果属性值中含有中文,读出来有可能是乱码的问题,根据SWIG生成的C#代码调试发现问题所在,在Ogr.cs文件中有这么一个函数,代码如下:
internal static string Utf8BytesToString(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
return null;
int length = Marshal.PtrToStringAnsi(pNativeData).Length; //问题在这句
byte[] strbuf = new byte[length];
Marshal.Copy(pNativeData, strbuf, 0, length);
return System.Text.Encoding.UTF8.GetString(strbuf);
}
问题就出现在上面这句中,如果shp文件中dbf的编码是utf-8的时候,pNativeData实际上就是GDAL库读取到的一个const char*的地址,这个时候,使用Marshal.PtrToStringAnsi函数返回的长度会变小,下面举个栗子:
如果GDAL的C++库返回的const char* pszValue = “中”,那么pNativeData的值实际上就是pszValue这个地址,且用UTF8编码的时候,pszValue指针对应的内存中的信息应该是”E4 B8 AD 00 XX XX”,后面的XX表示其他的东西,只有前四个有用。
这时pNativeData的值就是上面这个”E4 B8 AD 00 XX XX”字符串的地址,调用下面这句,返回的值居然是2。明明一个3的字符串为啥长度是2,就因为这里长度变短,导致后面转string的时候丢失了信息,造成了乱码。
int length = Marshal.PtrToStringAnsi(pNativeData).Length; //length = 2
本来想试下Marshal.PtrToString其他的函数,结果发现Marshal.PtrToStringAuto和Marshal.PtrToStringUni返回的长度都是16,就更不对了,没办法,用了一个笨办法,写了个循环来查找长度。修改后的代码如下:
internal static string Utf8BytesToString(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
return null;
int nMaxLength = Marshal.PtrToStringAuto(pNativeData).Length;
int length = 0;//循环查找字符串的长度
for(int i=0; i<nMaxLength; i++)
{
byte []strbuf1 = new byte[1];
Marshal.Copy(pNativeData+i, strbuf1, 0, 1);
if(strbuf1[0] == 0)
{
break;
}
length++;
}
byte[] strbuf = new byte[length];
Marshal.Copy(pNativeData, strbuf, 0, length);
return System.Text.Encoding.UTF8.GetString(strbuf);
}
同理,将Gdal.cs、Osr.cs这两个文件里面的这个函数也修改,重新编译即可解决这个问题。
最后,如果与shp中dbf的编码使用GBK之类的编码,请设置SHAPE_ENCODING这个配置项,如果shp文件夹中有同名的cpg文件则可以不用设置,但是确保cpg文件中写的编码与dbf中的实际编码相对应。
GDAL C#读取shp中文属性值乱码问题的更多相关文章
- GDAL C#中文路径,中文属性名称乱码问题
昨天写的博客,将C#读取shp中文属性值乱码的问题应该可以解决,博客地址为:http://blog.csdn.net/liminlu0314/article/details/54096119,然后又测 ...
- C# richtextbox 自动下拉到最后 方法 & RichTextBox读取txt中文后出现乱码
C# richtextbox 自动滚动到最后 光标到最后 自动显示最后一行 private void richTextBox1_TextChanged(object sender, EventArg ...
- 解决ArcGIS Engine AE 读取shapefile中文属性乱码的一条偏方
最近写一个程序,AE+C#,读shp字段属性,其中读到中文就乱码了 这个问题比较奇怪,用AE很多年了,怎么突然就乱码呢,用Arcmap打开,没乱码,证明不是数据问题 网上搜搜,很多人说是许可初始化的问 ...
- C++ AO读取shapefile的属性值
C++ AO读取一个shapefile文件的所有属性值 #include "stdafx.h" #include "iostream.h" #inc ...
- C# 读取XML节点属性值
xml文件格式如下: <?xml version="1.0" encoding="UTF-8" ?> <Product type=" ...
- java中Properties类及读取properties中属性值
本文为博主原创,未经允许不得转载: 在项目的应用中,经常将一些配置放入properties文件中,在代码应用中读取properties文件,就需要专门的类Properties类,通过这个类可以进行读取 ...
- PHP中使用DOM读取解析XML属性值一例
先看XML文件结构,与常见的文件略有不同,数据并不是用闭合标签保存的,而是直接保存在属性值中. <?xml version="1.0" encoding="utf- ...
- php读取mysql中文数据出现乱码
1.PHP页面语言本身的编码类型不合适,这时候,你直接在脚本中写的中文肯定是乱码,不用说数据库了: 解决方法:选择'UTF8'或者'gb2312',这样客户浏览器会自动选择并出现正确的中文显示. ...
- silverlight用Encoding.UTF8读取shape文件的中文属性值 出现乱码
最近用Silverlight读取shape文件,读出的属性居然是乱码. 原因是:Silverlight不支持GB2312. 解决方案: 下载该地址的代码http://encoding4silverli ...
随机推荐
- POJ-3292 Semi-prime H-numbers---筛素数
题目链接: https://vjudge.net/problem/POJ-3292 题目大意: 定义一种数叫H-numbers,它是所有能除以四余一的数. 在H-numbers中分三种数: 1.H-p ...
- 01、NetCore2.0优化之Web服务器 与 IIS解耦
01.NetCore2.0优化之Web服务器 与 IIS解耦 在Asp.Net Core 2.0中,是如何实现跨平台的?不使用IIS了,在linux上的WebServer是什么? ---------- ...
- MongoDB 更新文档
MongoDB 使用 update() 和 save() 方法来更新集合中的文档.接下来让我们详细来看下两个函数的应用及其区别. update() 方法 update() 方法用于更新已存在的文档.语 ...
- scrapy 选择器官方文档
当抓取网页时,常见的任务是从HTML源码中提取数据.现有的一些库可以达到这个目的: BeautifulSoup lxml Scrapy 提取数据有自己的一套机制.它们被称作选择器(seletors), ...
- else语句的搭配
1.else语句搭配if 要么怎样,要么怎样 2.else语句搭配for和while 干完循环之后执行else,干不完或者break就不执行 3.else与异常处理 没有问题的话就执行else吧
- 部署testlink报错,安装wampserver时提示丢失MSVCR110.dll
安装wampserver时提示丢失MSVCR110.dll(在windows server上可用)对于32位系统,安装Wampserver 后启动的时候提示系统错误:MSVCR110.dll丢失.于是 ...
- Redis、Memcache与MongoDB的区别
>>Memcached Memcached的优点:Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key.value的字节大小以及服务器硬件性能,日常环境 ...
- 在Unity3D中利用 RenderTexture 实现游戏内截图
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; publ ...
- 计蒜客 NOIP模拟赛(3) D1T1火山喷发
火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 nnn 个生物分别具有 A1,A2,⋯,An点生命值,一次火山喷发总计 M轮,每轮造成 1点伤害,等 ...
- UOJ #206. 【APIO2016】Gap
Description Solution 第一个子任务,直接从 \((a[i],a[j])\) 推出 \((a[i+1],a[j-1])\) 就行了,只需要 \(\frac{N+1}{2}\) 第二个 ...