李云尚, 余向东
(湖北省地质局 地球物理勘探大队,湖北 武汉 430056)
ArcGIS 是目前广泛使用的一种地理信息系统软件,主要用来制图、数据分析、各种专业地理信息系统的二次开发等。Shapefile文件是ArcGIS的基础文件类型,它主要用来存储点、线、多边形等几何对象的坐标信息和属性信息。目前很多城市的规划管理部门的地理地图都是采用Shapefile文件格式储存,而勘察部门基本都是使用CAD的dwg文件格式,因此,需要将Shapefile格式文件转换成为dwg格式文件。
ArcGIS的一个Shapefile文件实际上是一个文件夹,它里面主要包含一个主文件(xxx.shp),一个索引文件(xxx.shx),一个dbase格式的属性文件(xxx.dbf)。这三个文件中的数据既相互联系有各有区别,主文件(xxx.shp)是储存坐标信息(空间位置),由固定长度的文件头和变长度空间数据记录组成;索引文件(xxx.shx)是对主文件的索引,主要包含坐标文件的索引信息;属性文件(xxx.dbf)记录属性信息(地名,单位名,长度,高程,子图名,编码等),它是一个标准的DBF文件,是由头文件和实体信息两部分构成。
xxx.shp文件由文件头和文件记录构成,而每个记录是由固定长度的记录头和变长度的记录内容组成。
1.1.1 主文件头的组织结构
主文件头是100个字节的固定长度,以下是它的部分结构(表1)。
表1 主文件头结构表Table 1 Structure table of main file header
注:位置是指开始字节到文件头第一字节的偏移量,长度从0~99,刚好100个字节。
1.1.2 主文件记录的组织结构
每条记录由记录头和记录内容两部分组成,记录头结构见表2。
表2 记录头结构表Table 2 Structure table of record header
记录内容对于不同的Shapefile文件类型而不一样,长度也不一样,以二维点(point)类型的文件记录内容来说明(表3)。
所以二维点文件的记录内容长度是4+8+8=20
表3 二维点文件记录内容说明表Table 3 Explanatory table of 2d document content
个字节,每条记录的长度是4+4+20=28个字节,也就是14个字,是个固定长度(0是指到记录内容的开始字节的偏移量)。
DBF文件是dbase格式的数据文件,它记录.shp文件的属性数据,它在.shp文件中有特殊规定:
(1) 文件名前缀必须与xxx.shp和xxx.shx一样。
(2) 每一个图形特征必须在一个记录内。
(3) 记录顺序必须与xxx.shp文件的记录顺序一样。
图1 二维点文件转换为CAD文件流程图Fig.1 Flow chart of conversion of two dimensional point files into CAD file
利用二进制方式打开.shp文件,利用数据对象连接和打开.dbf文件,以下是程序片段:
Open FileName For Binary As #2 //打开.shp文件
ReDim myx(3)As Byte
Get #2,25,myx //从第25字节处开始读入4个字节
P=Val(b_l_h(myx))* 2 //计算文件总字节长度
Close #2 //关闭.shp文件
Set mywks=DBEngine.Workspaces(0) //创建工作空间
Set mydb=mywks.OpenDatabase(pathstr,True,True,“dbase 5.0”) //打开指定的数据库
Set myrs=mydb.OpenRecordset(filedbf,dbOpenSnapshot) //打开指定的表,创建记录集对象
Set mytab=mydb.TableDefs(filedbf) //创建表定义对象
........
k=(p-100)/28 //计算.shp文件的记录个数
........
Open FileName For Binary As #4 //二进制打开.shp文件
For i=1 To k
mystr=myrs.Fields(findval).Value //读取.dbf 文件第i行记录的指定字段的值
Set cad3dpoint=New clsmypoint //创建自定义对象实例
cad3dpoints.Add cad3dpoint //自定义对象添加到集合中
Set cad3dpoint=Nothing //对象清空
myrs.MoveNext //将记录对象的记录指针移到下一个记录
Next i
Close #4 //关闭.shp文件
myrs.Close //关闭记录对象
mydb.Close //关闭数据库对象
程序片段如下:
Set myx1.acadapp=GetObject(,“autocad.Application”) //引用cad应用程序对象
Set myx2.acaddoc=myx1.acadapp.ActiveDocument //引用一个cad活动文档对象
.........
geshu=cad3dpoints.Count //返回集合中对象的个数
For i=1 To geshu
Set cad3dpoint=New clsmypoint //创建自定义对象的实例
Set cad3dpoint=cad3dpoints.Item(i) //集合中的对象赋值给自定义对象
cad3dpoint.mylayer=layerming //给自定义对象的图层属性赋值
cad3dpoint.zhandian //调用自定义对象方法创建cad点对象
cad3dpoint.zhantext //调用自定义对象方法创建cad文本对象
Set cad3dpoint=Nothing //对象清空
Next i
通过上述文件的分析和代码演示,向大家展示了怎样用VB程序将Shapefile文件转换成cad文件的一般过程。通过工程实际运用,证实此方法确实可行,既方便又灵活,可以满足很多个性化的需求。
[1] 张国宝.AutoCAD 2000 VBA开发技术[M].北京:清华大学出版社,2000.
[2] 杨冬.Shapefile图形文件的数据存储格式及读写[J].首都师范大学学报(自然科学版),2010,31(2):4-8.