Dwg数据大概由BlockTable、LayerTable、TextStyleTable、LinetypeTable等
所有的数据都是存放在BlockTable对象中,BlockTableRecord是BlockTable的记录对象。
Dwg的CurrentSpaceId也是BlockTableRecord对象,块对象是递归包含关系。
一般的遍历dwg数据写法是
BlockTableRecord blockTableRecord = (BlockTableRecord)DwgDatabase.CurrentSpaceId.GetObject(OpenMode.ForRead);
foreach (ObjectId item in blockTableRecord)
{
Entity entity=item.GetObject(OpenMode.ForRead) as Entity;
//遍历实体进行转换
}
dwg图层信息是存放在LayerTable中,LayerTableRecord是图层记录对象。
获取图层代码
//name参数是图层名称
using (LayerTable outPutLayerTable = database.LayerTableId.GetObject(OpenMode.ForRead) as LayerTable)
{
if (outPutLayerTable.Has(name))
{
return outPutLayerTable[name].GetObject(OpenMode.ForRead) as LayerTableRecord;
}
}
dwg全局字体样式都存放在TextStyleTable中,TextStyleTableRecord是字体样式记录对象。
获取字体样式代码
//name参数是字体样式名称
using (TextStyleTable textStyleTable = database.TextStyleTableId.GetObject(OpenMode.ForRead) as TextStyleTable)
{
if (textStyleTable.Has(name))
{
return textStyleTable[name].GetObject(OpenMode.ForRead) as TextStyleTableRecord;
}
}
dwg全局线性样式都存放在LinetypeTable中,LinetypeTableRecord是样式记录对象。
获取线性样式代码
//name参数是线性样式编码
using (LinetypeTable linetypeTable = database.LinetypeTableId.GetObject(OpenMode.ForRead) as LinetypeTable)
{
if (linetypeTable.Has(name))
{
return linetypeTable[name].GetObject(OpenMode.ForRead) as LinetypeTableRecord;
}
}
在做dwg数据格式解析时,可以通过实体的类型名称来区分实体类型,进而进行针对性的数据解析。
这里区分了简单的类型,有些类型是没有去识别。
简单代码
string name = entity.GetType().Name;
try
{
switch (name)
{
case "DBText":
OnConvertDBText(entity as DBText);
break;
case "MText":
OnConvertMText(entity as MText);
break;
case "DBPoint":
OnConvertDBPoint(entity as DBPoint);
break;
case "Line":
OnConvertLine(entity as Line);
break;
case "Polyline":
OnConvertPolyline(entity as Polyline);
break;
case "Polyline2d":
OnConvertPolyline2d(entity as Polyline2d);
break;
case "Polyline3d":
OnConvertPolyline3d(entity as Polyline3d);
break;
case "Circle":
OnConvertCircle(entity as Circle);
break;
case "Arc":
OnConvertArc(entity as Arc);
break;
case "Ellipse":
OnConvertEllipse(entity as Ellipse);
break;
case "Spline":
OnConvertSpline(entity as Spline);
break;
case "BlockReference":
OnConvertBlockReference(entity as BlockReference);
break;
default:
OnConvertOthers(name, entity);
break;
}
}
catch (Exception ex)
{
AddErrorLogItem($"编号为({entity.ObjectId.OldIdPtr})、类型为({name})的数据转换错误,{ex.Message}");
}
DBPoint坐标信息存储在Position对象,获取代码
dBPoint.Position.X;
dBPoint.Position.Y;
Line数据表示两个点的简单直线,只有起点和终点
坐标信息分别存储在StartPoint、EndPoint中
line.StartPoint.X;
line.StartPoint.Y;
line.EndPoint.X;
line.EndPoint.Y;
Polyline表示多线段对象,是一组连续的点集组成的多线。
坐标信息需要遍历NumberOfVertices获取
//NumberOfVertices表示点集长度
for (int i = 0; i < polyline.NumberOfVertices; i++)
{
Point2d point2D = polyline.GetPoint2dAt(i);
point2D.X;
point2D.Y;
//如果线段是闭合的转换需要闭合线段
if (i == polyline.NumberOfVertices - 1 && polyline.Closed)
{
polyline.GetPoint2dAt(0).X;
polyline.GetPoint2dAt(0).Y;
}
}
Polyline2d二维多段线,类似多线段
但获取坐标代码不一样,因为对象设计结构不同。
且有时候存储的对象类型不一定一致,有可能是ObjectId,有可能是Vertex2d
Vertex2d startVertex2d = null;
foreach (object item in polyline2D)
{
Vertex2d vertex2D = null;
if (item is ObjectId)
{
vertex2D = ((ObjectId)item).GetObject(OpenMode.ForRead) as Vertex2d;
}
else if (item is Vertex2d)
{
vertex2D = item as Vertex2d;
}
if (startVertex2d == null)
{
startVertex2d = vertex2D;
}
shapeFiles.Vertices.Add(vertex2D.Position.X, vertex2D.Position.Y);
}
Polyline3d三维多线段,底层设计上跟二维的一样,所以代码差不多
PolylineVertex3d startPolylineVertex3d = null;
foreach (object item in polyline3D)
{
PolylineVertex3d polylineVertex3D = null;
if (item is ObjectId)
{
polylineVertex3D = ((ObjectId)item).GetObject(OpenMode.ForRead) as PolylineVertex3d;
}
else if (item is PolylineVertex3d)
{
polylineVertex3D = item as PolylineVertex3d;
}
if (startPolylineVertex3d == null)
{
startPolylineVertex3d = polylineVertex3D;
}
shapeFiles.Vertices.Add(polylineVertex3D.Position.X, polylineVertex3D.Position.Y);
}
Circle表示圆形,Arc表示圆弧,其实这两个可以用一个对象。圆形跟圆弧区别只是起始角度和终止角度不同而已。
在做dwg数据转换中,如果目标格式shp,因为shp不支持特殊图形,如圆、圆弧、曲线等,需要自己写算法将其转换成普通线段进行拟合。
circle.Center;中心点
circle.Radius;圆形的半径
arc.StartAngle;圆弧的起始角度
arc.EndAngle;圆弧的终止角度