Shapefile与CAD图形属性数据相互转换方法研究
2021-10-27刘凯程胡隽杉
刘凯程 胡隽杉
(1.东莞市测绘院,广东 东莞 523000;2.漯河市土地与房屋勘查测绘队,河南 漯河 462000)
0 引言
Shapefile文件的属性数据存储在与其根名相同的dbf文件中,CAD文件可以将图元对象的属性信息附加到与其关联的扩展数据 (XData)中。在ArcGIS中,可以直接在图层中添加CAD数据,也可以将Shapefile图形数据导出至CAD,但两者之间不能直接进行属性数据的转换。该文通过对Shapefile文件属性列表中的关键词段(数据类型为对象ID)和CAD图形中图元的对象ID(ObjectID)的对照研究,找出了二者之间的关联,进而使其属性数据能够进行相互转换。
1 Shapefile图形的对象ID与CAD图元的ObjectID对比分析
1.1 CAD图形的属性信息及扩展数据
为了试验和验证,该文结合“TEST宗地图 .dwg”文件的CAD 样予以说明。该文件中的宗地图用CASS软件绘制,已经添加了宗地号、权利人和地类号等属性数据。为了试验方便,删除了除界址线之外的所有图元。实际上,CASS的宗地属性数据就是附加在宗地图形上的扩展数据,其中最基本的属性数据存放在“SOUTH”应用下。
为了进行查验分析,用CAD自带的VBA开发工具编写一个宏“ElementInfo()”用来查询图元信息及扩展数据。该宏通过访问图元的ObjectID属性来获取其对象ID,通过调用图元的GetXData方法来获取其扩展数据,最后调用MsgBox()函数显示上述数据。
在CAD中打开文件“TEST宗地图.dwg”,运行宏ElementInfo(),选择图中的1个宗地界址线,将会弹出1个信息窗显示该宗地的图元对象ID及宗地属性(图1)。
图1 CASS软件宗地界址线的扩展数据
第一行为该宗地的图元对象ID值,数据类型为长整数(Long),在VBA中可通过访问图形对象的ObjectID属性获取。第2行之后为扩展数据的组码值类型和值,其中组码值类型“1001” 为扩展数据的注册应用名,“1000” 为扩展数据中的ASCII 字符串,在VBA中可用GetXData方法将它们读取到数组xtypeOut和xdataOut中。可以看出,xdataOut(0)= “SOUTH”,是CASS软件定义的一个应用名,宗地的基本属性数据存放在该应用下;xdataOut(1)= “300000”是CASS软件内部识别宗地图元的特殊标志;xdataOut(2)为宗地编号,xdataOut(3)为权利人,xdataOut(4)为地类编码[1]。
根据上述分析,可以编写一段程序代码将图形中所有图元的属性信息及扩展数据读取出来,生成1个Excel表。在ArcGIS中,可以将该表与该CAD文件转换的Shapefile文件属性表相连接,进而实现二者属性数据的转换[2]。
1.2 读取CAD属性生成Excel表
上面已经介绍,在VBA中可用CAD元的ObjectID属性 和GetXData方法读取对象ID和扩展数据,为了在ArcGIS中与Shapefile属性表相连接,需要将CAD图形文件中所有的图元信息全部读取出来。为此,可以通过编写宏“ExportXData()”来实现。该宏首先启动Excel并创建一个工作薄,然后读取CAD模型空间内所有图元的指定属性和扩展数据,将其添加到第一个工作表,同时按读取顺序在第一列生成一个由0开始的序号。将该工作薄保存为“TEST宗地属性表.xls”(图2)。
图2 CAD导出的宗地属性表
在1个CAD文件中,各图元的对象ID(ObjectID)和句柄(Handle)都是唯一的,对象ID 和唯一的句柄是引用对象的2个途径。ObjectID值是十进制整数,是按照图元创建的顺序由小到大生成的。Handle值十六进制字符串,转换为十进制整数后也是由小到大的顺序。该文采用ObjectID引用对象[3]。
与Shapefile文件不同,CAD图元的对象ID是不连续的整数,为与Shapefile属性表相关联,需要在CAD导出的Excel表中设置1个充当主关键词的字段,在该字段中按照ObjectID由小到大的顺序确定主关键词段的值:第一条记录为0,第n条记录为n-1。
该文实验数据中的主关键词段名为“FID”,确定CAD图元的“FID”字段值有2种方法。
方法1:将所有图元对象加入一个选择集(SelectionSet)中,通过遍历该选择集的办法将ObjectID和其他扩展数据导出为Excel表,按照ObjectID的升序进行排序,将第一条记录的FID值赋为0,以后各行依次+1即可。也可以在遍历选择集时采用倒序的方法,这样导出的顺序便是ObjectID由小到大的顺序,就不用再排序了。
方法2:CAD的ModelSpace图元集对象中包括了图形中所有的图元,图元在ModelSpace中的排列顺序就是ObjectID值由小到大的顺序。因此,只需按顺序遍历ModelSpace,将图元的ObjectID和其他扩展数据导出到Excel表,同时将第一条记录的FID值赋为0,以后各行依次+1即可。该文中的宏“ExportXData”采用的就是该方法[4]。
1.3 Shapefile文件属性表
启动ArcMap,新建空白地图,把CAD样该文件“TEST宗地图.dwg”添加进图层。将面图层“TEST宗地图.dwg Polygon”导出为Shapefile文件“TEST宗地图.shp”并添加进来。打开“TEST宗地图”图层的属性表,添加一个用于计算面积的字段“Area”进行对比分析,数据类型选“双精度型”,用“几何计算”功能计算该出字段的面积值(图3)。
对照图2和图3中的面积字段“Area”可以看出,CAD导出的“TEST宗地属性表.xls”和ArcGIS中的“TEST宗地图”属性表所关联图元的排列顺序是一致的,主关键词“FID”也完全相同。这样,在ArcGIS中就可以根据主关键词将这2个属性表连接起来。
图3 ArcGIS中的宗地属性表
2 CAD到Shapefile的属性转换
2.1 将Excel连接到Shapefile属性表
将从CAD导出的Excel表添加到ArcGIS,然后用主关键词段将其与Shapefile文件的属性表进行连接,具体操作如下。
在ArcGIS的图层中添加“TEST宗地属性表.xls”,添加时选择第一个工作表“Sheet1$”。 在“TEST宗地图”图层上点击右键,在弹出的下拉式菜单中点击“连接和关联”,接着点击“连接…”。在弹出的“连接数据”对话框中“1.选择该图层中连接将基于的字段”选“FID”, “2.选择此表中要作为连接基础的字段”也选“FID”,其余选项取默认值,点击“确定”按钮。
打开“TEST宗地图”图层的属性表,可以看出2个属性表已经连接起来了。
2.2 将被连接的CAD属性加入Shapefile属性表
将表“Sheet1$”中的宗地字段加入“TEST宗地图.shp”文件的属性中,可以采用如下3种方法。
方法1:在连接后的属性表中添加需要加进来的字段,定义好字段名和数据类型,然后利用字段计算器把“Sheet1$”中对应的字段抄录过来。
方法2:将连接后的属性表导出为一个新的dbf文件,移除 “TEST宗地图”图层,在文件夹中删除“TEST宗地图.dbf”文件,将导出的dbf文件重命名为“TEST宗地图.dbf”,最后在ArcGIS图层中重新添加“TEST宗地图.shp”。
方法3:将连接属性后的“TEST宗地图.shp”导出为1个新的Shapefile文件并添加到ArcGIS图层中,移除 “TEST宗地图”图层,在文件夹中删除根名为“TEST宗地图”的所有文件,将导出的Shapefile系列文件的根名批量重命名为“TEST宗地图”。
最后,打开属性表,删除掉不需要的字段。通过上述操作,就可以将CAD图形的属性和扩展数据转换为Shapefile文件的属性表。
3 Shapefile到CAD的属性转换
3.1 Shapefile文件预处理
3.1.1 确保Shapefile的dbf文件为ANSI编码
有时,Shapefile文件的dbf属性表用Excel打开后中文会显示为乱码,这是因为Shapefile文件不是ANSI格式。可通过修改Windows注册表解决该问题。
打开注册表编辑器,定位到HKEY_CURRENT_USERSoftwareESRIDesktop 10.8(根据实际安装的版本而定)。新建 “Common”项,在其下再新建“CodePage”项,新建字符串值,名称为“dbfDefault”,健值为“ANSI”。 重新导出Shapefile文件,打开dbf文件就显示正常了。导出后还要在注册表中把“dbfDefault”的健值改为“UTF-8”,否则在ArcMap中打开的Shapefile文件属性表的中文又变成了乱码。
3.1.2 确保导出的CAD图形为多段线
在ArcGIS中,由添加的CAD文件导出的Shapefile文件属性表“Shape”字段中会包括“ZM”值,Z值是高程属性,M值是其他属性。包括“ZM”值的Shapefile文件导出为CAD后,线和面变成了三维多段线。三维多段线没有面积属性,多数情况下还需要将其变为多段线。CAD中没有直接将三维多段线转为多段线的工具,需要在转换前将Shapefile图形的“ZM”值去除掉。具体操作如下:1) 点击主菜单“地理处理”,打开“ArcToolbox”工具箱,依次展开“数据管理工具”、“要素”,打开“复制要素”对话框。2) 在“输入要素”组合框中选择原Shapefile文件,在“输出要素”文本框输入目标Shapefile文件位置和名,点击“环境…”按钮,打开“环境设置” 对话框。3) 将“输出包括M值”和“输出包括Z值”均设置为“Disabled”, 点击“确定”按钮。
返回“复制要素”对话框中点击“确定”按钮。
3.2 CAD属性数据的存储模式
在ArcGIS中,Shapefile文件导出的CAD图形并没有包括图元所关联的属性数据。
可以采取如下2种模式存储CAD属性数据:1) 用ADO建立CAD与外部数据库dbf表的连接。但这种连接在CAD存储位置发生改变时会失效,须重新设置连接的数据源。2) 直接将属性信息存储在CAD图元的扩展数据中。在这种模式中,属性信息是附加在CAD图元上的,是CAD图元的组成部分,会随CAD图形的复制、转移而携带。在CAD二次开发中一般多采用这种模式,该文介绍的就是这种模式[5]。
3.3 Shapefile的dbf文件数据导入CAD
Shapefile文件的属性数据实际上存储在与其根名相同的dbf文件中,其与Shapefile之间的关联主要是靠数据类型为“对象ID”的主关键词段,这个字段的名字一般为“FID” 或“OBJECTID”。 这个dbf文件中每条记录的主关键词段值对应一个Shapefile图形的对象ID。在一个Shapefile文件中,各图形的对象ID是从0开始的连续的整数。
将Shapefile的dbf文件中的记录按主关键词段的升序进行排序,在CAD中打开导出的CAD文件,逐条读取dbf文件记录,按照CAD图元ObjectID的升序用SetXData方法写入其扩展数据中,即可实现Shapefile到CAD的属性转换。如下2种方法均可实现上述目的。
方法1:将dbf导入一个数据库中,然后再通过ADO连接访问该dbf表,读取表中的记录写入CAD图元的扩展数据中。这种方法需要安装相应的数据库管理软件。
方法2:这是1个比较简单的方法。在Excel中直接打开dbf文件,按主关键词段的升序对其进行排序,然后逐行读取Excel数据,按照CAD图元ObjectID属性值由小到大的顺序写入其扩展数据中。
该文采用的是方法2,并为此编写了宏“ImportXData()”来辅助实现。该宏通过遍历Eccel活动工作表中除标题行外的所有行,读取指定单元格数据,然后以该顺序号为索引,用CAD模型空间对象ModelSpace的Item()方法访问相应的图元,为该图元附加扩展数据。下面是一个操作实例。
(1)在ArcMap中添加“TEST宗地图.shp”,将其导出为CAD文件“TEST宗地图1.dwg”。
(2)在Excel中打开“TEST宗地图.dbf”, 按“FID”字段的升序对其进行排序。
(3)运行宏“ImportXData()”,将Excel数据写入CAD。
经上述操作, Shapefile的dbf文件数据被导入了对应的CAD图元扩展数据中。用宏“ElementInfo()”查询图元信息,与ArcMap中识别的图形属性进行对比,会发现二者是一一对应的。
4 结语
笔者通过上述文件的分析和代码演示,向大家展示了怎样用VBA程序将Shapefile图形及其属性数据转换成CAD图形及扩展数据的一般过程。通过该文中实际运用,证实该方法确实可行可靠,既方便又灵活,可以满足我们很多个性化的需求。希望该文能为今后大家解决这类问题提供一个思路。