FloorSystemItem.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:FloorSystemItems
  3. * 作者:xulisong
  4. * 创建时间: 2019/1/4 17:50:04
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text.RegularExpressions;
  11. using Autodesk.Revit.DB;
  12. using Autodesk.Revit.DB.Mechanical;
  13. using SAGA.DotNetUtils.Data;
  14. using SAGA.DotNetUtils.Extend;
  15. using SAGA.Models;
  16. using SAGA.RevitUtils;
  17. using SAGA.RevitUtils.Extends;
  18. using SAGA.RevitUtils.MEP;
  19. namespace SAGA.GplotRelationComputerManage
  20. {
  21. public class FloorSystemItem
  22. {
  23. #region 构造函数
  24. /// <summary>
  25. /// 初始化解析类
  26. /// </summary>
  27. /// <param name="doc"></param>
  28. public FloorSystemItem(Document doc)
  29. {
  30. Document = doc;
  31. InitData();
  32. }
  33. #endregion
  34. #region 属性相关
  35. /// <summary>
  36. /// 关联模型信息
  37. /// </summary>
  38. public Document Document { get; private set; }
  39. /// <summary>
  40. /// 使用关联标高
  41. /// </summary>
  42. public Level UseLevel { get; private set; }
  43. private bool m_IsInited;
  44. /// <summary>
  45. /// 初始化数据
  46. /// </summary>
  47. private void InitData()
  48. {
  49. if (m_IsInited)
  50. return;
  51. UseLevel = Document.GetUseView()?.GenLevel;
  52. m_IsInited = true;
  53. }
  54. #endregion
  55. #region 开始节点获取
  56. /// <summary>
  57. /// 缓存信息
  58. /// </summary>
  59. private List<StringFlag<ElementTreeNode>> m_StartNodes;
  60. /// <summary>
  61. /// 按系统获取开始节点
  62. /// </summary>
  63. /// <returns></returns>
  64. private List<StringFlag<ElementTreeNode>> GetStartNodes()
  65. {
  66. if (m_StartNodes != null)
  67. {
  68. //返回没有处理过的节点信息
  69. return m_StartNodes.Where(s => !s.Handled).ToList();
  70. }
  71. List<StringFlag<ElementTreeNode>> startNodes = new List<StringFlag<ElementTreeNode>>();
  72. var doc = Document;
  73. #region 立管处理
  74. /*
  75. * 暂时认定,一个立管之关联一个系统
  76. */
  77. var verticalPipes = doc.GetElements<MEPCurve>().Where(p => SystemCalcUtil.IsStart(p) && p.IsVerticalPipe());
  78. foreach (var verticalPipe in verticalPipes)
  79. {
  80. ElementTreeNode node = new ElementTreeNode();
  81. node.Current = verticalPipe;
  82. var systemTypeName = verticalPipe.GetSystemTypeName();
  83. startNodes.Add(new StringFlag<ElementTreeNode>(systemTypeName, node));
  84. }
  85. #endregion
  86. #region 特殊阀门处理
  87. ElementCategoryFilter pipeFilter = new ElementCategoryFilter(BuiltInCategory.OST_PipeAccessory);
  88. ElementCategoryFilter ductFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctAccessory);
  89. ElementFilter filter = new LogicalOrFilter(pipeFilter, ductFilter);
  90. var specialValves = doc.FilterElements(filter).Where(f => SystemCalcUtil.IsStart(f));
  91. foreach (var familyInstance in specialValves)
  92. {
  93. var connector = familyInstance.GetAllConnectors()
  94. .FirstOrDefault(c => Regex.IsMatch(c.Description, AppSetting.EndFlag));
  95. if (connector == null)
  96. continue;
  97. var node = SystemParseManager.CreateTreeNode(familyInstance, connector, e => e is MEPCurve);
  98. var useMepCurve = node.GetLeaves().FirstOrDefault()?.Current as MEPCurve;
  99. if (useMepCurve == null)
  100. continue;
  101. var systemTypeName = useMepCurve.GetSystemTypeName();
  102. startNodes.Add(new StringFlag<ElementTreeNode>(systemTypeName, node));
  103. }
  104. #endregion
  105. return m_StartNodes = startNodes;
  106. }
  107. private List<StringFlag<Element>> m_RoomStartElements;
  108. /// <summary>
  109. /// 获取机房开始元素
  110. /// </summary>
  111. /// <param name="relationSetting"></param>
  112. /// <returns></returns>
  113. private List<Element> GetRoomStartNodes(RelationTypeShell relationSetting)
  114. {
  115. if (m_RoomStartElements == null)
  116. {
  117. m_RoomStartElements = new List<StringFlag<Element>>();
  118. ElementCategoryFilter pipeFilter = new ElementCategoryFilter(BuiltInCategory.OST_PipeAccessory);
  119. ElementCategoryFilter ductFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctAccessory);
  120. ElementFilter filter = new LogicalOrFilter(pipeFilter, ductFilter);
  121. var specialValves = Document.FilterElements(filter).Where(f => SystemCalcUtil.IsStart(f));
  122. foreach (var familyInstance in specialValves)
  123. {
  124. var connector = familyInstance.GetAllConnectors()
  125. .FirstOrDefault(c => Regex.IsMatch(c.Description, AppSetting.SourceFlag));
  126. if (connector == null)
  127. continue;
  128. var node = SystemParseManager.CreateTreeNode(familyInstance, connector, e => e is MEPCurve);
  129. var useMepCurve = node.GetLeaves().FirstOrDefault()?.Current as MEPCurve;
  130. if (useMepCurve == null)
  131. continue;
  132. var systemTypeName = useMepCurve.GetSystemTypeName();
  133. m_RoomStartElements.Add(new StringFlag<Element>(systemTypeName, familyInstance));
  134. }
  135. }
  136. return m_RoomStartElements.Where(f => relationSetting.IsMatchSystem(f.Flag)).Select(f => f.Instance)
  137. .ToList();
  138. }
  139. #endregion
  140. #region 设备节点获取
  141. private List<EquipmentConnectionItem> m_ConnectionItems ;
  142. /// <summary>
  143. /// 通过设备类型获取相关设备
  144. /// </summary>
  145. /// <returns></returns>
  146. private List<FamilyInstance> GetEquipments(Domain domain,RelationTypeShell shell)
  147. {
  148. #region 初始化
  149. if (m_ConnectionItems == null)
  150. {
  151. var tempItems = new List<EquipmentConnectionItem>();
  152. var doc = Document;
  153. var fies = doc.FilterElements<FamilyInstance>();
  154. foreach (var familyInstance in fies)
  155. {
  156. var familyName = familyInstance.GetFamily().Name;
  157. if (string.IsNullOrEmpty(familyName))
  158. continue;
  159. var match = Regex.Match(familyName, @"^(?:((?:[A-Z][A-Z]){2,3})\s*-\s*\S*)");
  160. if (match.Success)
  161. {
  162. var connectors = familyInstance.GetAllConnectors();
  163. foreach (var connector in connectors)
  164. {
  165. try
  166. {
  167. if (connector.IsConnected && (connector.Domain == Domain.DomainPiping || connector.Domain == Domain.DomainHvac))
  168. {
  169. tempItems.Add(new EquipmentConnectionItem(connector));
  170. }
  171. }
  172. catch (Exception)
  173. {
  174. }
  175. }
  176. }
  177. }
  178. m_ConnectionItems = tempItems;
  179. }
  180. #endregion
  181. List<FamilyInstance> result = new List<FamilyInstance>();
  182. foreach (var connectionItem in m_ConnectionItems)
  183. {
  184. if (connectionItem.Used)
  185. {
  186. continue;
  187. }
  188. if (connectionItem.Domain == domain && shell.IsMatchSystem(connectionItem.SystemTypeName)&&connectionItem.Equipment is FamilyInstance equipment)
  189. {
  190. result.Add(equipment);
  191. connectionItem.Used = true;
  192. }
  193. }
  194. return result.Distinct().ToList();
  195. }
  196. #region 过时
  197. ///// <summary>
  198. ///// 模型中包含的设备
  199. ///// </summary>
  200. //public Dictionary<string, List<FamilyInstance>> RevitEquipments { get; private set; }
  201. ///// <summary>
  202. ///// 通过设备类型获取相关设备
  203. ///// </summary>
  204. ///// <returns></returns>
  205. //private List<FamilyInstance> GetEquipments(string category)
  206. //{
  207. // if (RevitEquipments == null)
  208. // {
  209. // var doc = Document;
  210. // var fies = doc.FilterElements<FamilyInstance>();
  211. // List<StringFlag<FamilyInstance>> original = new List<StringFlag<FamilyInstance>>();
  212. // foreach (var familyInstance in fies)
  213. // {
  214. // var familyName = familyInstance.GetFamily().Name;
  215. // if (string.IsNullOrEmpty(familyName))
  216. // continue;
  217. // var match = Regex.Match(familyName, @"^(?:((?:[A-Z][A-Z]){2,3})\s*-\s*\S*)");
  218. // if (match.Success)
  219. // {
  220. // original.Add(new StringFlag<FamilyInstance>(match.Groups[1].ToString(), familyInstance));
  221. // }
  222. // }
  223. // RevitEquipments = original.GroupBy(f => f.Flag)
  224. // .ToDictionary(g => g.Key, g => g.ToList().Select(f => f.Instance).ToList());
  225. // }
  226. // RevitEquipments.TryGetValue(category, out List<FamilyInstance> result);
  227. // return result ?? new List<FamilyInstance>();
  228. //}
  229. #endregion
  230. #endregion
  231. #region 数据解析方法
  232. /// <summary>
  233. /// 解析当前楼层系统数据
  234. /// </summary>
  235. /// <param name="context"></param>
  236. public virtual void Parse(SystemComputerContext context)
  237. {
  238. if (UseLevel == null)
  239. return;
  240. var relations = context.Relations;
  241. foreach (var relation in relations)
  242. {
  243. var shell = context.RelationShells.GetItem(relation);
  244. if (shell.IsPipeSystem())
  245. {
  246. ParsePipe(context, shell,Domain.DomainPiping);
  247. }
  248. else
  249. {
  250. ParseDuct(context, shell);
  251. }
  252. }
  253. }
  254. #region 水系统解析
  255. public void ParsePipe(SystemComputerContext context, RelationTypeShell relationSetting, Domain currentDomain)
  256. {
  257. Domain useDomain = currentDomain;
  258. var relationType = relationSetting.RelationItem.Type;
  259. List<FloorDrawRecord> drawRecords = new List<FloorDrawRecord>();
  260. List<FloorRelationRecord> relationRecords = new List<FloorRelationRecord>();
  261. #region 计算拓扑树形结构
  262. /*
  263. * 1、遍历开始点的限制:特殊阀门,指定标注的Connector;立管,已连接连接件;空间,相交风管元素;
  264. * 2、根据拓扑图关联的对象信息,找到系统关联的设备生成节点。如果没有遍历到要独立生成
  265. * 3、要不要显示端头管所在空间的位置
  266. */
  267. var startNodes = GetStartNodes();
  268. HashSet<int> useIds = new HashSet<int>();
  269. List<MEPCurve> verticalMepCurves = new List<MEPCurve>();
  270. for (int i = 0; i < startNodes.Count; i++)
  271. {
  272. var startNode = startNodes[i];
  273. var useRelation = relationSetting.GetFirstMatchSystem(startNode.Flag);
  274. if (useRelation == null)
  275. continue;
  276. if (useIds.Contains(startNode.Instance.Current.Id.IntegerValue))
  277. {
  278. continue;
  279. }
  280. //加入立管
  281. if (startNode.Instance.Current is MEPCurve mepCurve)
  282. {
  283. verticalMepCurves.Add(mepCurve);
  284. }
  285. var tempIds = SystemParseManager.BuildSystemNode(startNode.Instance, useDomain,
  286. (m => !startNode.Flag.Equals(m.GetSystemTypeName())));
  287. startNode.Instance.PipeSystemTypeName = startNode.Flag;
  288. BuildElementNodeData(context, startNode.Instance);
  289. useIds.UnionWith(tempIds);
  290. startNode.Handled = true;
  291. //可以清空Leaves的子节点
  292. #region 整理原始数据
  293. //判断是否有设备节点,不进行数据处理
  294. var useNode = startNode.Instance;
  295. //var firstEquipment = useNode.FirstOrDefault(t => MBIInfoUtil.IsEquipment(t.Current));
  296. //要不要以这个为判定条件,图形可以画出,关系肯定是没有的
  297. //if (firstEquipment != null)
  298. if (useNode.Nodes.Any())
  299. {
  300. //存在设备则保存信息
  301. var drawRecord = BuildFloorDrawRecord(relationSetting, useNode);
  302. drawRecord.SystemName = startNode.Flag;
  303. drawRecords.Add(drawRecord);
  304. var relationRecord = BuildFloorRelationRecord(relationSetting, useNode,context);
  305. relationRecords.Add(relationRecord);
  306. }
  307. #endregion
  308. }
  309. #region 解析机房数据
  310. var roomStartElements = GetRoomStartNodes(relationSetting);
  311. var useEquipments = ParseMachineRoomData(context, relationSetting, roomStartElements);
  312. useEquipments = useEquipments.Distinct().ToList();
  313. #endregion
  314. //获取没有使用过的对象节点
  315. List<FamilyInstance> singleInstances = GetEquipments(useDomain, relationSetting);
  316. for (int i = 0; i < singleInstances.Count; i++)
  317. {
  318. var useInstance = singleInstances[i];
  319. if (useIds.Contains(useInstance.Id.IntegerValue) || useEquipments.Any(id => id == useInstance.Id.ToString()))
  320. {
  321. continue;
  322. }
  323. var connectors = useInstance.GetAllConnectors();
  324. foreach (var connector in connectors)
  325. {
  326. if (connector.Domain != useDomain)
  327. {
  328. continue;
  329. }
  330. var startNode = SystemParseManager.CreateTreeNode(useInstance, connector, e => e is MEPCurve);
  331. //查找需要遍历的路径信息
  332. var leaves = startNode.GetLeaves();
  333. //使用过的系统不再进行遍历
  334. List<string> useSystems = new List<string>();
  335. foreach (var leaf in leaves)
  336. {
  337. var useMepCurve = leaf?.Current as MEPCurve;
  338. if (useMepCurve == null)
  339. continue;
  340. var systemTypeName = useMepCurve.GetSystemTypeName();
  341. if (!relationSetting.IsMatchSystem(systemTypeName))
  342. {
  343. continue;
  344. }
  345. if (useSystems.Any(s => s == systemTypeName))
  346. {
  347. continue;
  348. }
  349. useSystems.Add(systemTypeName);
  350. //创建指定的startNode;[一个分支,一个分支去处理]
  351. ElementTreeNode newStartNode = new ElementTreeNode() {Current = useInstance};
  352. var tempIds = SystemParseManager.BuildSystemNode(newStartNode, useDomain,
  353. (m => !systemTypeName.Equals(m.GetSystemTypeName())));
  354. newStartNode.PipeSystemTypeName = systemTypeName;
  355. BuildElementNodeData(context, newStartNode);
  356. useIds.UnionWith(tempIds);
  357. #region 生成绘图,计算数据
  358. //解析数据,找管道定系统,管道找不到,系统名为"关联类型-未知"
  359. var drawRecord = BuildFloorDrawRecord(relationSetting, newStartNode);
  360. drawRecord.SystemName = systemTypeName;
  361. drawRecords.Add(drawRecord);
  362. var relationRecord = BuildFloorRelationRecord(relationSetting, newStartNode, context);
  363. relationRecords.Add(relationRecord);
  364. #endregion
  365. }
  366. }
  367. }
  368. #endregion
  369. //增加立管数据
  370. ComputerVerticalPipes(UseLevel, verticalMepCurves, context, relationSetting);
  371. context[relationType].FloorDrawRecords.AddRange(drawRecords);
  372. context[relationType].FloorRelationRecords.AddRange(relationRecords);
  373. }
  374. #endregion
  375. #region 风系统解析
  376. public void ParseDuct(SystemComputerContext context, RelationTypeShell relationSetting)
  377. {
  378. ParsePipe(context, relationSetting, Domain.DomainHvac);
  379. }
  380. #endregion
  381. #endregion
  382. #region 解析立管
  383. private void SetAttachBuilding(VerticalPipe vp,MEPCurve mepCurve)
  384. {
  385. vp.FloorId = mepCurve.Document.PathName.GetFileName();
  386. vp.BuildingName = MBIInfoUtil.GetBuildingName(vp.FloorId);
  387. vp.BuildingId = MBIInfoUtil.GetBuildingId(vp.FloorId);
  388. }
  389. /*
  390. * 1、解析立管需要考虑,竖直风管,水管,空间的情况;
  391. *2、将各层数据汇总,才能统一计算立管的相关关系数据
  392. */
  393. private void ComputerVerticalPipes(Level refLevel, List<MEPCurve> mepCurves, SystemComputerContext context, RelationTypeShell relationSetting)
  394. {
  395. var result = new List<VerticalPipe>();
  396. var spaces = Document.GetElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).OfType<Space>();
  397. var level = refLevel;
  398. var relationType = relationSetting.RelationItem.Type;
  399. var currentLevelName = MBIInfoUtil.GetFloorNameByLevel(level.Name);
  400. foreach (var pipe in mepCurves)
  401. {
  402. if (pipe == null)
  403. continue;
  404. var vp = new VerticalPipe
  405. {
  406. Id = pipe.Id.IntegerValue.ToString(),
  407. LevelName = currentLevelName,
  408. LevelId=level.Id.ToString(),
  409. LevelElevation = level.Elevation,
  410. UpPoint3D = PointConverter.XYZToPoint3D(pipe.GetVerticalTopPoint()),
  411. DownPoint3D = PointConverter.XYZToPoint3D(pipe.GetVerticalBottomPoint()),
  412. PipeSytemType = pipe.GetSystemTypeName()
  413. };
  414. SetAttachBuilding(vp,pipe);
  415. vp.FloorName = currentLevelName;
  416. #region 获取立管关联空间
  417. var locationCurve = pipe.GetLocationCurve();
  418. var midPoint = (locationCurve.StartPoint() + locationCurve.EndPoint()) / 2;
  419. Space refSpace = spaces.FirstOrDefault(s => s.IsPointInSpace(midPoint)); //关联
  420. var display = context.GetSpaceDisplay(refSpace, out string tip);
  421. vp.Display = $"{display}:{pipe.Id.IntegerValue.ToString()}";
  422. vp.DisplayTip = tip ?? string.Empty;
  423. #endregion
  424. result.Add(vp);
  425. }
  426. LevelData levelData = new LevelData()
  427. {
  428. Id = refLevel.Id.ToString(),
  429. Name = MBIInfoUtil.GetFloorNameByLevel(refLevel.Name),
  430. FloorId = Document.PathName.GetFileName(),
  431. Elevation = refLevel.Elevation,
  432. };
  433. levelData.BuildingName = MBIInfoUtil.GetBuildingName(levelData.FloorId);
  434. levelData.BuildingId = MBIInfoUtil.GetBuildingId(levelData.FloorId);
  435. context[relationType].VerticalPipes.AddRange(result);
  436. context[relationType].Levels.Add(levelData);
  437. }
  438. #endregion
  439. #region 保存数据类对象创建
  440. private string GetUnknownSystemName(RelationTypeShell relationShell)
  441. {
  442. return relationShell.RelationItem?.Name + "---未知";
  443. }
  444. private FloorDrawRecord BuildFloorDrawRecord(RelationTypeShell relationShell, ElementTreeNode node)
  445. {
  446. var floorDraw = new FloorDrawRecord();
  447. floorDraw.SetFloorLevel(UseLevel);
  448. floorDraw.RelationType = relationShell.RelationItem.Type;
  449. floorDraw.DrawIems = SystemParseManager.CreateDrawing(node) ?? new SystemDrawItems();
  450. return floorDraw;
  451. }
  452. private FloorRelationRecord BuildFloorRelationRecord(RelationTypeShell relationShell, ElementTreeNode node, SystemComputerContext context)
  453. {
  454. var floorRelation = new FloorRelationRecord();
  455. floorRelation.SetFloorLevel(UseLevel);
  456. floorRelation.RelationType = relationShell.RelationItem.Type;
  457. var records= SystemParseManager.CreateRelation(node) ?? new List<BinaryRelationItem>();
  458. floorRelation.RelationItems = records;
  459. var mathSystem=relationShell.GetFirstMatchSystem(node.PipeSystemTypeName);
  460. var edgeType = mathSystem.ContainEdgeTypes.FirstOrDefault();
  461. if(string.IsNullOrWhiteSpace(edgeType))
  462. {
  463. edgeType = "1";
  464. }
  465. //增加关联对象名称
  466. records.ForEach(e => {
  467. var nodes = new List<EquipmentNode>() { e.From, e.To };
  468. nodes.ForEach(n => n.MbiId = context.EquipmentItems.GetItem(n.BimId)?.Id);
  469. e.RelationType = edgeType;
  470. if(mathSystem!=null&&mathSystem.FlowType==FlowType.Out)
  471. {
  472. //根据流向反转关系
  473. e.Reverse();
  474. }
  475. });
  476. return floorRelation;
  477. }
  478. #endregion
  479. #region 初始化名称,分类
  480. /// <summary>
  481. /// 初始化节点扩展数据
  482. /// </summary>
  483. /// <param name="context"></param>
  484. /// <param name="node"></param>
  485. private void BuildElementNodeData(SystemComputerContext context, ElementTreeNode node)
  486. {
  487. Queue<ElementTreeNode> nodeQueue = new Queue<ElementTreeNode>();
  488. nodeQueue.Enqueue(node);
  489. while (nodeQueue.Any())
  490. {
  491. #region 控制验证
  492. var currentNode = nodeQueue.Dequeue();
  493. if (currentNode == null)
  494. continue;
  495. var element = currentNode.Current;
  496. if (element == null)
  497. continue;
  498. #endregion
  499. if (element is FamilyInstance fiEq)
  500. {
  501. #region 判断是否是设备
  502. if (MBIInfoUtil.IsEquipment(fiEq))
  503. {
  504. var equipItem = context.EquipmentItems.GetItem(fiEq.GetBimId());
  505. NodeExtendData data = new NodeExtendData();
  506. if (equipItem != null)
  507. {
  508. data.Name = equipItem.GetDisplay();
  509. data.Category = equipItem.Category;
  510. }
  511. else
  512. {
  513. data.Name = fiEq.GetFamily()?.Name;
  514. }
  515. data.SystemType = node.PipeSystemTypeName;
  516. currentNode.Tag = data;
  517. }
  518. #endregion
  519. }
  520. else if (element is Space revitSpace)
  521. {
  522. var space = context.Rooms.GetItem(element.GetBimId());
  523. NodeExtendData data = new NodeExtendData();
  524. if (space != null)
  525. {
  526. data.Name = space.GetDisplay();
  527. }
  528. else
  529. {
  530. data.Name = revitSpace.Name;
  531. }
  532. data.SystemType = node.PipeSystemTypeName;
  533. currentNode.Tag = data;
  534. }
  535. currentNode.Nodes.ForEach(e => nodeQueue.Enqueue(e));
  536. }
  537. }
  538. #endregion
  539. #region 解析机房数据
  540. /// <summary>
  541. /// 解析机房数据
  542. /// </summary>
  543. /// <param name="context"></param>
  544. /// <param name="relationSetting"></param>
  545. /// <param name="startElements"></param>
  546. protected List<string> ParseMachineRoomData(SystemComputerContext context, RelationTypeShell relationSetting,
  547. List<Element> startElements)
  548. {
  549. /*
  550. *1、解析过程中尽量少处理和后续相关的数据
  551. * 2、设备整理,带缓存的设备信息读取
  552. */
  553. List<string> useEquipments = new List<string>();
  554. var relationType = relationSetting.RelationItem.Type;
  555. GplotGraphParse parse = new GplotGraphParse(new GplotGraphSetting(relationSetting));
  556. List<Element> useStartElements = new List<Element>(startElements);
  557. var graphs = parse.CreateGplotGraphs(useStartElements);
  558. graphs.RemoveAll(c => c.Vertexes.All(v => !v.IsRealEquipment()));
  559. #region 加载设备显示信息
  560. foreach (var elementEdgesArray in graphs)
  561. {
  562. var vertexes = elementEdgesArray.Vertexes.Where(v => v.Children.Count == 0);
  563. foreach (var elementsVertex in vertexes)
  564. {
  565. var equipmentItem = elementsVertex.GetEquipment();
  566. if (equipmentItem == null)
  567. {
  568. continue;
  569. }
  570. if (string.IsNullOrWhiteSpace(equipmentItem.BimId))
  571. {
  572. continue;
  573. }
  574. if (equipmentItem.ElementType == ElementType.Space)
  575. {
  576. var spaceIem = context.Rooms.GetItem(equipmentItem.BimId);
  577. if (spaceIem != null)
  578. {
  579. equipmentItem.Name = spaceIem.GetDisplay();
  580. }
  581. }
  582. else if (equipmentItem.ElementType == ElementType.Equipment)
  583. {
  584. var equipment = context.EquipmentItems.GetItem(equipmentItem.BimId);
  585. if (equipment != null)
  586. {
  587. equipmentItem.Name = equipment.GetDisplay();
  588. }
  589. }
  590. }
  591. }
  592. #endregion
  593. #region 生成图形数据
  594. var drawData = SystemParseManager.CreateRoomDrawing(graphs);
  595. MachineRoomDrawRecord record = new MachineRoomDrawRecord();
  596. record.RelationName = relationSetting.RelationItem.Name;
  597. record.NodePaths = drawData;
  598. record.SetFloorLevel(UseLevel);
  599. context[relationType].MachineRoomDrawRecords.Add(record);
  600. #endregion
  601. #region 生成关系数据
  602. var relations = SystemParseManager.CreateRoomRelation(graphs);
  603. MachineRoomRelationRecord relationRecord = new MachineRoomRelationRecord();
  604. relationRecord.SetFloorLevel(UseLevel);
  605. relationRecord.RelationName = relationSetting.RelationItem.Name;
  606. foreach (var item in relations)
  607. {
  608. var node = new BinaryRelationItem();
  609. node.From = ConverEquipmentNode(item.EquipmentItem1, context);
  610. node.To = ConverEquipmentNode(item.EquipmentItem2, context);
  611. node.RelationType = item.LinkType;
  612. relationRecord.RelationItems.Add(node);
  613. var newIds = new List<string>() { item.EquipmentItem1.Id, item.EquipmentItem2.Id };
  614. useEquipments.AddRange(newIds);
  615. }
  616. context[relationType].MachineRoomRelationRecords.Add(relationRecord);
  617. #endregion
  618. return useEquipments;
  619. }
  620. private EquipmentNode ConverEquipmentNode(EquipmentItem item, SystemComputerContext context)
  621. {
  622. EquipmentNode result = new EquipmentNode();
  623. result.IsRealEquipment = !item.IsVirtual;
  624. result.RevitId = item.Id;
  625. result.BimId = CreateBimId(result.RevitId);
  626. var equipment = context.EquipmentItems.GetItem(result.BimId);
  627. if (equipment != null)
  628. {
  629. result.MbiId = equipment.Id ?? string.Empty;
  630. result.Category = equipment.Category;
  631. }
  632. else
  633. {
  634. result.Category = MBIInfoUtil.GetEquipmentCategory(item.Name) ?? string.Empty;
  635. }
  636. return result;
  637. }
  638. #endregion 解析机房数据
  639. /// <summary>
  640. /// 根据revitId获取bimId
  641. /// </summary>
  642. /// <param name="revitId"></param>
  643. /// <returns></returns>
  644. private string CreateBimId(string revitId)
  645. {
  646. return string.Format($"{Document.PathName.GetFileName()}:{revitId}");
  647. }
  648. }
  649. }