关于sharp map 的中文编码问题
2010-05-19 17:22 废墟中的垃圾 阅读(1692) 评论(1) 收藏 举报关于 sharp map 的文章其实很多了
这里我所有的文字都是自己的心得,但是不敢说原创,因为都是取材于前辈们的经验。我会慢慢的写整个sharp map 的系列包括很多网上找不到的技术。sharp map本身是开源的,基于他开发的程序应该也需要开源,但是实际上在中国大家都是不分享的。特别是你问了某些前辈,他们就说给你一个思路,实际上真的没有给什么帮助。我这里不是指责那些不分享成果的人,毕竟路遥自己走,但是一个简单的Demo也许真的会帮助很多人。
好了开始今天的正题:
前提:读取shp文件(其他格式没有测试)
只要是用过 sharp map 的朋友都知道 在读取数据文件的时候,如果是中文就会出现乱码。如果不分析 sharp map的源程序,只看官方的demo是不能解决问题的。
这里也是官方的一个疏忽(个人认为是)。因为在我们读取shp文件的时候,使用了这样的方式:
//Set up a river layer
SharpMap.Layers.VectorLayer layRivers = new SharpMap.Layers.VectorLayer("Rivers");
//Set the datasource to a shapefile in the App_data folder
nts = new NtsProvider(new SharpMap.Data.Providers.ShapeFile(HttpContext.Current.Server.MapPath(@"~\App_data\rivers.shp"), true));
layRivers.DataSource = nts; //Define a blue 1px wide pen
layRivers.Style.Line = new Pen(Color.Blue, 1);
layRivers.SRID = 4326;
这样在文件读取的时候就有一个问题,没有地方有编码相关的信息。
那么我们跟踪一下看一下文件读取的过程
会发现在 SharpMap.Data.Providers.DbaseReader.cs
里面有关于编码的方法:private Encoding GetDbaseLanguageDriver(byte dbasecode)
使用官方的shp文件,发现编码是 ANSI
这里要注意的是,不是很多人说的因为默认编码是utf7所以导致乱码,而是因为Sharp map 在没有设置编码的情况会读取文件的编码,然后读取文件。而官方给的和平时我们到处的shp文件都是 ANSI 编码。所以就出了问题。
继续跟踪会发现 读取数据 是通过private object ReadDbfValue(DbaseField dbf) 方法读取的。
case "System.String":
if (_Encoding == null)
return _FileEncoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim();
else
return _Encoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim();
这里的编码如果没有设置,那么就是文件的编码读取了。
如果只是想解决中文读取的问题,那么第一个方法出来了。修改这段程序为:
case "System.String":
return Encoding.Default.GetString(br.ReadBytes(dbf.Length)).Replace("12", "").Trim();
通过测试可以通过。
其实开始的时候我说了,导致我们不知道怎么处理中文编码有一点 就是官方给的代码有一点问题。这里当然不是说他运行错误。
而且我们可以把代码修改一下,修改成:
//Set up a river layer
SharpMap.Layers.VectorLayer layRivers = new SharpMap.Layers.VectorLayer("Rivers");
//Set the datasource to a shapefile in the App_data folder
ShapeFile sf = new SharpMap.Data.Providers.ShapeFile(HttpContext.Current.Server.MapPath(@"~\App_data\rivers.shp"), true);
sf.Encoding = System.Text.Encoding.GetEncoding("gb2312");
nts = new NtsProvider(sf);
layRivers.DataSource = nts; //Define a blue 1px wide pen
layRivers.Style.Line = new Pen(Color.Blue, 1);
layRivers.SRID = 4326;
大家看到了吧,只要独立创建一个 ShapeFile 对象,这样就可以设置读取时候的编码了。
ok了 两个方法都告诉大家了。希望对大家有所帮助。
浙公网安备 33010602011771号