CASS数据转Access数据库的方法探讨
2015-03-30张国宏
张国宏
(清远市勘察测绘院,广东 清远511515)
一、引 言
CASS成图系统是基于AutoCAD平台二次开发出来的产品,因AutoCAD简单易学,操作方便灵活,能以多种方式创建直线、圆、椭圆、多边形、样条曲线等基本图形对象,因此CASS成图系统在测量领域应用广泛。随着测量技术的不断完善,GIS逐步运用到测量领域中,并逐渐成为主导,ArcGIS软件平台是当前主流的地理信息系统应用平台之一。GIS操作的对象是空间数据和属性数据,Esri公司的Geodatabase数据模型采用全关系数据库管理空间数据,与各种商用关系数据库兼容。Geodatabase提供了Personal Geodatabase可伸缩的空间数据存储方案,适用于单机环境下的GIS应用,实际上就是一个Access数据库,通过Microsoft Jet Engine将空间数据存放在Access数据库中,将空间几何信息、属性信息,拓扑信息、三维信息及多媒体信息有机地结合在一起。本文拟使用C#.NET语言,来探讨CASS数据转化成ArcGIS软件平台支持的Access数据库的方法。
二、数据库框架结构建立
1.Access数据结构
ArcGIS 数据结构是空间数据和关系数据的结合,为了更好地展现所包含的信息,每个图形都包含与之相对应的属性,并根据要素属性编码显示对应的符号。其数据分层严格按照几何类型划分,如点、线、面、文字等,同一图层中只能含有一种几何类型。因此,Access数据结构可以用代码创建或在ArcCatalog下创建,数据结构的OBJECTID、SHAPE字段是创建结构时自动产生的,不可缺少。其中,OBJECTID字段用来存储数据的自动编号;SHAPE字段的数据类型是OLE对象,用来存储空间几何坐标(X,Y,Z),该字段的值可以设置或读取,是一个非常重要的字段;CASSCODE、FEATURENAME、ANGLE是扩展字段,可以使用Microsoft Office Access 2003软件创建修改,用来存储属性数据(见表1)。
表1 Access数据结构
2.CASS数据结构
CASS图形保存的数据为AutoCAD格式,图形中的图层、颜色、线型、线宽、填充、图块等基本信息都是利用AutoCAD的机制来存储,数据图层可以任意放置不同类型的对象,对象的基本属性信息全部存储在DXF群码里,CASS编码存储在对象的XData扩展数据里,并用该编码来显示对应的符号。实例为:
((-1.<图元名:7ef759a8>)(0."INSERT")(330.<图元名:7ef73cc0>)(5."4A5")(100."AcDbEntity")(67.0)(410."Model")(8."GCD")(6."Continuous")(100."AcDbBlockReference")(66.1)(2."GC200")(10 244.31 70.4556 11.0)(41.0.5)(42.0.5)(43.0.5)(50.0.0)(70.0)(71.0)(44.0.0)(45.0.0)(210 0.0 0.0 1.0)(-3("SOUTH"(1000."202101"))))
三、获取CASS数据几何坐标及属性
CASS数据转换到Access数据库实质就是图形的几何要素重写的过程,获取对象的几何坐标及相关的属性信息、CASS编码并按照一定数据格式重新组成一个新的数据文件。
CASS数据几何类型分布在不同的图层中,获取几何坐标时首先判断对象的几何类型,因为不同的几何类型获取坐标的方式不一样。在对象的XData扩展数据获取CASS编码并关联INDEX.INI文件调用实体名称,把获取到CASS编码和实体名称分别写入CASSCODE和FEATURENAME字段里存储。如图1所示。
图1 INDEX.INI
1.点状地物几何坐标及属性获取
CASS数据点状地物是以块的方式来定义的(如稻田、菜地等),块的插入点即为该点状地物的几何坐标。获取点状地物的几何坐标时先要获取该实体BlockReference对象的Position属性值,该属性值返回的是Point3d坐标。获取点状地物几何坐标及属性代码段如下:
foreach(ObjectId id in SSet.GetObjectIds())
{
Entity entity=id.GetObject(OpenMode.ForRead)as Entity;
string objType=entity.GetType().Name;
string cassAttrib=zgh_XData.zgh_getXData(db,id);
string[]cassAttArry;
string cassCode="";
if(cassAttrib!="")
{
cassAttArry=cassAttrib.Split(',');
cassCode=cassAttArry[1].ToString();∥CASS编码
}
string layer=entity.Layer;∥图层
int colorIndex=entity.ColorIndex;∥颜色
string cassName=
zgh_Access.zgh_getAccessTableFiledValue(odcConnection,
cassCode);∥实体名称
if(objType=="BlockReference"&layer=="DMTZ")
{
BlockReference block=entity as
BlockReference;
Point3d position=block.Position;
string angle=
zgh_MatchFormula.zgh_RadianConvertDegree(block.Rotation).
ToString();∥角度
∥对象类型*图层*颜色*cass编码*实体名称*角度*X*Y*Z
string coordString=objType+"*"+layer+"*"+colorIndex+"*"+cassCode+"*"+cassName+"*"+angle+"*"+position.X.ToString()+","+position.Y.ToString()+","+position.Z.ToString();
DMTZ_Point_List.Add(coordString);
}
}
2.线状地物几何坐标及属性获取
CASS数据线状地物分为多段线和二维多段线,它们的坐标获取的方式不一样,多段线的坐标直接用GetPoint3dAt方法获取,返回的是Point3d类型的坐标。获取二维多段线的坐标时先要把二维多段线Polyline2d转换成Vertex2d对象类型,获取该对象下的Position属性值,其返回的是Point3d类型坐标。
(1)获取多段线坐标代码段
相关代码如下:
for(int i=0;i<pline.NumberOfVertices;i++)
{
Point3d Point=pline.GetPoint3dAt(i);
}
(2)获取二维多段线坐标代码段
相关代码如下:
foreach(ObjectId vid in pline2d)
{
Vertex2d v2d=trans.GetObject(vid,
OpenMode.ForWrite)as Vertex2d;
Point3d Point=v2d.Position;
}
(3)获取线状地物几何坐标及属性代码段
相关代码如下:
foreach(ObjectId id in SSet.GetObjectIds())
{
Entity entity=id.GetObject(OpenMode.ForRead)as Entity;
string objType=entity.GetType().Name;
string cassAttrib=zgh_XData.zgh_getXData(db,id);
string[]cassAttArry;
string cassCode="";
if(cassAttrib!="")
{
cassAttArry=cassAttrib.Split(',');
cassCode=cassAttArry[1].ToString();∥CASS编码
}
string layer=entity.Layer;∥图层
int colorIndex=entity.ColorIndex;∥颜色
string cassName=
zgh_Access.zgh_getAccessTableFiledValue(odcConnection,cassCode);∥实体名称
if(objType=="Polyline"&layer=="DMTZ")∥多段线
{
Autodesk.AutoCAD.DatabaseServices.Polyline pline=entity as
Autodesk.AutoCAD.DatabaseServices.Polyline;
string xyzString=
zgh_polyline.zgh_getPLineXYZCoord(pline);
∥对象类型*图层*颜色*线型*cass编码*实体名称*坐标
string coordString=objType+"*"+layer+"*"+colorIndex+"*"+lineType+"*"+cassCode+"*"+cassName+"*"+xyzString;
DMTZ_Polyline_List.Add(coordString);
}
if(objType=="Polyline2d"&layer=="DMTZ")∥二维多段线
{
Polyline2d pline2d=entity as Polyline2d;
string xyzString=
zgh_polyline.zgh_get2PLineXYZCoord(trans,pline2d);
tryError=tryError+","+xyzString;
string coordString=objType+"*"+layer+"*"+colorIndex+"*"+lineType+"*"+cassCode+"*"+cassName+"*"+xyzString;
DMTZ_Polyline_List.Add(coordString);∥将数据添加到坐标信息集
}
}
3.面状地物几何坐标及属性获取
CASS数据面状地物都是由多段线构成,如一般房屋等。面状地物的对象Closed属性值等于true,仅凭这一点很难准确地分析出面状地物,因为有些线状地物Closed属性值也等于true,这时需要获取对象的XData扩展数据CASS编码关联INDEX.INI文件来判断。面状地物几何坐标的获取与线状地物几何坐标的获取方法一样,唯一不同的是面状地物顶点坐标首尾需闭合,否则在ArcMap中不能正常显示。
4.文字几何坐标及属性获取
CASS数据的文字信息获取比较简单,坐标存储在对象的AlignmentPoint属性里,返回的是Point3d坐标。文字内容在对象的TextString属性里,返回的string。文字角度在Rotation属性里,返回的是double。
获取文字几何坐标及属性代码段相关代码如下:
foreach(ObjectId id in SSet.GetObjectIds())
{
Entity entity=id.GetObject(OpenMode.ForRead)as Entity;
string objType=entity.GetType().Name;
string cassAttrib=zgh_XData.zgh_getXData(db,id);
string[]cassAttArry;
string cassCode="";
if(cassAttrib!="")
{
cassAttArry=cassAttrib.Split(',');
cassCode=cassAttArry[1].ToString();∥CASS编码
}
string layer=entity.Layer;∥图层
int colorIndex=entity.ColorIndex;∥颜色
string cassName=
zgh_Access.zgh_getAccessTableFiledValue(odcConnection,cassCode);∥实体名称
if(objType=="DBText"&layer=="DMTZ")
{
DBText textEntity=entity as DBText;
string textString=textEntity.TextString;
string textHeight=
textEntity.Height.ToString("0.00");
string textAngle=
zgh_MatchFormula.zgh_RadianConvertDegree(textEntity.Rotation).ToString("0.000000");
Point3d position=textEntity.AlignmentPoint;
∥对象类型*图层*颜色*文字内容*字高*角度*cass编码*实体名称*X*Y*Z
string coordString=objType+"*"+layer+"*"+colorIndex+"*"+textString+"*"+textHeight+"*"+textAngle+"*"+cassCode+"*"+cassName+"*"+position.X.ToString()+","+position.Y.ToString();
DMTZ_Text_List.Add(coordString);
}
}
四、向Access数据库写入空间数据及关系数据
在开始写入数据前,需要先获取图层的要素类,该要素类的FeatureClass属性提供了要素类的返回,将获取的要素类转为IDataset集合,该接口的Workspace属性可以获取到要素类的工作空间。编辑工作空间继承自工作空间,提供了两对方法:StartEding和StopEding、StartEditOperation和StopEditOperation。其中StartEditOperation和StopEditOperation必须在StartEding方法之后,在StopEding方法之前执行形成一个闭合的嵌套结构。通过CreateFeature方法创建一个新的要素对象,该对象的Shape属性用于设置或获取对象的几何形状,如点、线、面。set_Value方法用于设置字段的属性值。Store方法用于存储数据。向Access数据库写入空间数据及关系数据代码如下:
IFeatureLayer qFeatureLayer=layer as
IFeatureLayer;
IFeatureClass qFeatureClass=
qFeatureLayer.FeatureClass;
IDataset dataset=qFeatureClass as IDataset;
IWorkspaceEdit qWorkspaceEdit=
dataset.Workspace as IWorkspaceEdit;
qWorkspaceEdit.StartEditing(true);
qWorkspaceEdit.StartEditOperation();
IFeature qFeature=
qFeatureClass.CreateFeature();
Point point=new Point();
double x=Convert.ToDouble(coordArry[0]);∥X
double y=Convert.ToDouble(coordArry[1]);∥Y
point.PutCoords(x,y);
qFeature.Shape=point as IGeometry;
qFeature.set_Value(2,"202101");
qFeature.set_Value(3,"一般高程点");
qFeature.set_Value(4,0);
qFeature.Store();
qWorkspaceEdit.StopEditOperation();
qWorkspaceEdit.StopEditing(true);
五、试验结果
根据转换前、后的图形比较检查,发现其几何要素、CASS属性未发现遗漏,效果较为理想。
转换前数据如图2所示。
图2 转换前数据
转换后数据如图3所示。
图3 转换后数据
六、结束语
通过试验分析,本文介绍的方法能够方便地将CASS数据转换到ArcGIS支持的Access数据库,能够实现数据分层和属性构建,以及必要的属性内容转换,可以较直观地实现基于ArcGIS的基础地形图库动态更新。
[1] 邱洪钢,张青莲,熊友谊.ArcGIS Engine地理信息系统开发从入门到精通[M].北京:人民邮电出版社,2013:34-35,125.
[2] 兰小机,刘德儿,魏瑞娟.基于ArcObjects与C#.NET的GIS应用开发[M].北京:冶金工业出版社,2013:215.
[3] 曾洪飞,卢择临,张帆.AutoCAD VBA&VB.NET开发基础与实例教程(C#版)[M].北京:中国电力出版社,2013.