代码改变世界

关于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了 两个方法都告诉大家了。希望对大家有所帮助。