自己动手读取显示shp文件
(2010-08-17 14:15:29)
shp文件的数据结构网上到处都可以查到,主要是:文件头(共100 bytes)记录头 记录项记录头 记录项....... ................. ..........存储的图元可能是点,多点,多线,面,都是基础几何信息。用.net的BinaryRead类带的可以很方便的读取,暂时只做了点的处理,根据记录项的不同,用不同的几何数据结构去序列化,因为C#正常情况下不使用指针,所以无法自己手动申请内存,只有用List<>去存储,可能有时会浪费一点,但比较方便。shp文件的结构还算简单,所以也没遇到什么难题,只是文件头的前几十个字节是big Endian的需要自己去写一个转换成Little Endian的方法,起初在网上查了很多资料都实现的很复杂,结果自己想清楚了以后,用BitConvert转换两次,只三行代码就搞定了.另外一个要注意的地方是:C#里是用的unicode编码,char是占两个字节的字符型,而byte才是占一个字节的整型,这一点与C++不同,在写数据结构的时候可能容易搞混。
与之关联的dbf文件存储的是属性数据,dbf是dbase 4代的数据库文件,数据结构也还算简单,但是读到记录项的时候,却始终读出乱码,也不知道是不是数据结构的资料是错误的。后面直接用ado.net的oledbconnection对象连接,用SQL语句查询返回dataTable,反而更省事了想想其实这样操作dbf文件,还不如不用dbf文件当属性数据库,直接用mdb或者sqlite可能效果会更好,反正dbf与shp的相关性也不是那么高,只是几何数据与属性数据的id号通过shx对应即可。
把shp,dbf的结构搞清楚以后,也大概对一个小型的gis数据源有了认识,有点想自己重新设计一个结构的想法,把几何数据与数据设计在一起,存储在数据库中,那样处理以后会少很多功夫,似乎sqlserver2008已经实现了空间数据库的功能,还有少量的空间分析的功能,还没有来得及装起sqlserver2008试试效果,不过本次写程序的目的是为了练手,一切都用现成的,就失去意义了。
下一步就是显示了,也终于意识到自己的理论知识不够用了,只一个坐标系问题就有点考人。点shp文件里的坐标序列使用的坐标系可能不尽相同,可能是北京54,西安80,也可能是WGS1984,还好的是,都是已经投影过的平面坐标,不用自己再去拿参考椭球球找来自己映射。现在所要做的就是把平面坐标系转换成程序上的客户区坐标区。如果要打开不同坐标系的shp文件估计就要查很多资料了。投影坐标系都是笛卡尔坐标系,而屏幕坐标系或者客户区坐标系都是原点在左上角,向右,向下为正方向的坐标系,这里需要做一个还算简单的转换。然后要有一定的缩放比,这里又有了新的问题,因为一直用的GDI+的所有图元的结构体都是int或float型,原shp文件里都是double型,按一些大大们的说法,GDI+这会就像个玩具了,只要一缩放就要精度丢失不说,能不能正常显示都是个问题,而这个问题又是个比较重要的问题,要么自己重写所有涉及到的gdi+的方法,要么选择openGL4.net,现在自己为了能有个草图,都是强行转换成float型,有点囧。
下一步就要做一些日常的地图操作了包括放大,缩小,选中前两者都是坐标系的变换,倒还好说,选中几何图元的话,还没有想到比较好的方法,感觉挨个去遍历所有内存中的数据结构,肯定会很花时间。再一步就是要做一些标记,或者绘图的操作了基本上就是自己写一个简单的矢量画图程序了。想先在winForm上实现核心算法,再慢慢移植到siverlight上和WPF上。并且设计自己的存储结构。
喜欢
0
赠金笔
加载中,请稍候......