EMQX + InfluxDB:物联网设备数据采集与时序存储全链路实战
2026/10/16 11:11:48
Line(ZwSoft.ZwCAD.DatabaseServices.Line):纯粹两点直线实体,不支持线宽渐变、不能添加中间顶点,老管网部分标准会用到;Polyline多段线:管网主流,支持线宽、拐点;PipeGeomHelper增加CreatePipeLine工具方法;namespace CommPipe { /// <summary> /// 管线绘制交互模式 /// </summary> public enum PipeDrawMode { /// <summary>拾取屏幕两点,直接画线</summary> PickScreenPoint, /// <summary>拾取图上两个管点块实体,提取插入点画线</summary> PickExistPointEntity } /// <summary> /// 管线实体类型:Line简单直线 / Polyline多段线 /// </summary> public enum PipeEntityKind { Line, Polyline } }CodeDefine增加属性:
public PipeEntityKind PipeEntityKind { get; set; }/// <summary> /// 在模型空间创建简单Line直线实体 /// </summary> /// <param name="db">数据库</param> /// <param name="startPt">起点</param> /// <param name="endPt">终点</param> /// <param name="layerName">图层名</param> /// <returns>Line的ObjectId,失败返回Null</returns> public static ObjectId CreatePipeLine(Database db, Point3d startPt, Point3d endPt, string layerName) { if (db == null) return ObjectId.Null; try { using (var tr = db.TransactionManager.StartTransaction()) { ObjectId msId = SymbolUtilityServices.GetBlockModelSpaceId(db); BlockTableRecord ms = tr.GetObject(msId, OpenMode.ForWrite) as BlockTableRecord; if (ms == null) { tr.Abort(); return ObjectId.Null; } Line lineEnt = new Line(startPt, endPt); lineEnt.Layer = layerName ?? ""; ms.AppendEntity(lineEnt); tr.AddNewlyCreatedDBObject(lineEnt, true); tr.Commit(); return lineEnt.ObjectId; } } catch (Exception) { return ObjectId.Null; } }原有
CreatePipePolyline保留不动。
else if (curPipeType == CommPipe.PipeType.Line) { var layerDef = codeDefine.LayerInfo; string targetLayerName = layerDef.LayerKey; ZwSoft.ZwCAD.Colors.Color layerColor = LayerHelper.ParseRawColor(layerDef.ColorRaw); Point3d startPt = Point3d.Origin; Point3d endPt = Point3d.Origin; bool pickOk = false; // 根据配置选择绘制交互模式 if (codeDefine.LineDrawMode == CommPipe.PipeDrawMode.PickScreenPoint) { //模式A:拾取屏幕两点 PromptPointResult pt1 = ed.GetPoint("\n请拾取管线起点:"); if (pt1.Status != PromptStatus.OK) return; PromptPointResult pt2 = ed.GetPoint("\n请拾取管线终点:"); if (pt2.Status != PromptStatus.OK) return; startPt = pt1.Value; endPt = pt2.Value; pickOk = true; } else if (codeDefine.LineDrawMode == CommPipe.PipeDrawMode.PickExistPointEntity) { //模式B:拾取图上已存在管点块 if (!PipeGeomHelper.PickPipePointEntity(ed, "\n请拾取起始管点:", out startPt)) { ed.WriteMessage("\n拾取起始管点失败或用户取消"); return; } if (!PipeGeomHelper.PickPipePointEntity(ed, "\n请拾取终止管点:", out endPt)) { ed.WriteMessage("\n拾取终止管点失败或用户取消"); return; } pickOk = true; } if (!pickOk) { return; } //拾取完成之后,再确保图层存在 using (var trCheckLayer = db.TransactionManager.StartTransaction()) { if (!LayerHelper.IsLayerExists(trCheckLayer, db, targetLayerName)) { LayerHelper.EnsureLayerExist(trCheckLayer, db, targetLayerName, layerColor); } trCheckLayer.Commit(); } ObjectId pipeEntId = ObjectId.Null; if (codeDefine.PipeEntityKind == CommPipe.PipeEntityKind.Line) { // 创建原生Line直线 pipeEntId = PipeGeomHelper.CreatePipeLine(db, startPt, endPt, targetLayerName); } else { // 创建Polyline多段线 Point3dCollection pts = new Point3dCollection(); pts.Add(startPt); pts.Add(endPt); pipeEntId = PipeGeomHelper.CreatePipePolyline(db, pts, targetLayerName); } if (pipeEntId.IsNull) { ed.WriteMessage($"\n绘制管线【{codeDefine.Name}】失败"); return; } // Todo:给pipeEntId实体附加XData业务属性 // 如果是PickExistPointEntity模式,可把两个管点ObjectId写入XData做拓扑 ed.WriteMessage($"\n成功绘制管线【{codeDefine.Name}】"); }Line实体没有全局线宽属性,线宽要靠CAD图层线宽控制;而Polyline支持每段独立宽度;PipeEntityKind切换调用不同工具;Line/Polyline、拾取屏幕点 / 拾取已有管点。小提示:模式B
PickExistPointEntity当前只判断是BlockReference;后续可以增强PickPipePointEntity,校验块名,防止拾取别的无关块。
如果你需要,我可以把PickPipePointEntity改成重载版本,同时输出拾取到的管点ObjectId,方便后面写拓扑XData。