Browse Source

Merge branch 'master' of http://dev.dp.sagacloud.cn:8886/r/Revit/SAGA.MBI

mengxiangge 6 years ago
parent
commit
6567060292
53 changed files with 3024 additions and 293 deletions
  1. 3 3
      MBI/FirmLib/Com.FirmLib/Bll/EquipmentInfoPointBll.cs
  2. BIN
      MBI/MBIResource/Config/HttpSetting.xml
  3. BIN
      MBI/MBIResource/Config/物理世界关系定义列表-2019-1.xlsx
  4. 97 0
      MBI/SAGA.DotNetUtils/Cache/CacheItems.cs
  5. 67 0
      MBI/SAGA.DotNetUtils/Data/FlagDecorator.cs
  6. 12 3
      MBI/SAGA.DotNetUtils/NPOI/NPOIHelper.cs
  7. 2 0
      MBI/SAGA.DotNetUtils/SAGA.DotNetUtils.csproj
  8. 8 5
      MBI/SAGA.GplotManage/GplotCommand.cs
  9. 0 6
      MBI/SAGA.GplotManage/GplotManage/LocalDataUtil.cs
  10. 48 0
      MBI/SAGA.GplotRelationComputerManage/Common/AppSetting.cs
  11. 34 0
      MBI/SAGA.GplotRelationComputerManage/Common/DataServerUtil.cs
  12. 35 2
      MBI/SAGA.GplotRelationComputerManage/Common/MBIInfoUtil.cs
  13. 40 0
      MBI/SAGA.GplotRelationComputerManage/Common/PointConverter.cs
  14. 2 2
      MBI/SAGA.GplotRelationComputerManage/ComputerPipes.cs
  15. 0 17
      MBI/SAGA.GplotRelationComputerManage/ComputerVerticalPipe.cs
  16. 138 0
      MBI/SAGA.GplotRelationComputerManage/DataServer/DataServer.cs
  17. 30 0
      MBI/SAGA.GplotRelationComputerManage/DataServer/FileKeyAttribute.cs
  18. 30 0
      MBI/SAGA.GplotRelationComputerManage/DataServer/IVersionFile.cs
  19. 191 0
      MBI/SAGA.GplotRelationComputerManage/DataServer/TimeVersionFile.cs
  20. 35 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/Data/EdgeItem.cs
  21. 107 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/Data/ObjectItem.cs
  22. 56 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/Data/RelationItem.cs
  23. 69 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/Data/SystemItem.cs
  24. 207 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/RelationTypeManager.cs
  25. 53 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/RelationTypeShell.cs
  26. 12 0
      MBI/SAGA.GplotRelationComputerManage/RelationType/read.txt
  27. 29 3
      MBI/SAGA.GplotRelationComputerManage/SAGA.GplotRelationComputerManage.csproj
  28. 31 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/PointItemType.cs
  29. 100 4
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/SystemCalcUtil.cs
  30. 370 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/SystemParseManager.cs
  31. 30 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/BinaryRelationItem.cs
  32. 39 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/EquipmentNode.cs
  33. 25 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SetRelationItem.cs
  34. 56 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemCurveItem.cs
  35. 30 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemDrawItems.cs
  36. 48 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemPointItem.cs
  37. 332 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/FloorSystemItem.cs
  38. 0 48
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/FloorSystemItems.cs
  39. 27 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorDrawRecord.cs
  40. 49 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorRecord.cs
  41. 23 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorRelationRecord.cs
  42. 67 22
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/SystemComputerContext.cs
  43. 37 0
      MBI/SAGA.GplotRelationComputerManage/SystemRelation/SystemComputerHandler.cs
  44. 31 13
      MBI/SAGA.MBI/Interaction/MBIModelInfoManager.cs
  45. 1 1
      MBI/SAGA.MBI/Model/MRevitEquipBase.cs
  46. 54 0
      MBI/SAGA.MBI/RevitModelHandle/ParameterDefinitionFactory.cs
  47. 183 0
      MBI/SAGA.MBI/RevitModelHandle/ParameterUtil.cs
  48. 99 86
      MBI/SAGA.MBI/RevitModelHandle/RevitParameterUpdate.cs
  49. 2 0
      MBI/SAGA.MBI/SAGA.MBI.csproj
  50. 47 0
      MBI/SAGA.Models/ChangesRelationship.cs
  51. 2 75
      MBI/SAGA.Models/StaticData.cs
  52. 3 3
      MBI/SAGA.RevitUtils/MEP/MepJoinUtil.cs
  53. 33 0
      MBI/SAGA.RevitUtils/MEP/TNode.cs

+ 3 - 3
MBI/FirmLib/Com.FirmLib/Bll/EquipmentInfoPointBll.cs

@@ -65,7 +65,7 @@ namespace Com.FirmLib.Bll
                         item.Remark = (string)subj["note"];
                         item.Classification = (string)subj["classification"];
                         item.IsShow = true;// (string)subj["is_mapped"] == "1";
-                        item.CollectionCmptCode = inputService?.GetInputCode(item.InputType)??item.InputType;//(string)subj["collection_cmpt_code"];
+                        item.CollectionCmptCode = inputService?.GetInputCode(item.InputType) ?? item.InputType;//(string)subj["collection_cmpt_code"];
                         items.Add(item);
                     }
 
@@ -80,7 +80,7 @@ namespace Com.FirmLib.Bll
         /// 获取自定义信息点
         /// </summary>
         /// <returns></returns>
-        public  List<EquipmentInfoPointItem> UserDefineSysOrEqInfos(string projectId,string code)
+        public List<EquipmentInfoPointItem> UserDefineSysOrEqInfos(string projectId, string code)
         {
             List<EquipmentInfoPointItem> items = new List<EquipmentInfoPointItem>();
             //由于使用了相关的项目,是不是可以不过滤这个
@@ -88,7 +88,7 @@ namespace Com.FirmLib.Bll
 
             HttpClient client = HttpClientManager.CreateClient();
             var result = client.GetAsync(new Uri(url, UriKind.RelativeOrAbsolute));
-             var stringResult = HandlerTaskResponse(result, new RequestInfo(url));
+            var stringResult = HandlerTaskResponse(result, new RequestInfo(url));
             var flag = HandlerResult(stringResult,
                 (jo) => {
                     var content = jo["Content"];

BIN
MBI/MBIResource/Config/HttpSetting.xml


BIN
MBI/MBIResource/Config/物理世界关系定义列表-2019-1.xlsx


+ 97 - 0
MBI/SAGA.DotNetUtils/Cache/CacheItems.cs

@@ -0,0 +1,97 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:CacheItems
+ * 作者:xulisong
+ * 创建时间: 2019/1/8 18:06:27
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.DotNetUtils.Cache
+{
+    public class CacheItems<ParameterT,ItemT> : Dictionary<string, ItemT>
+    {
+        /*
+         * 有的缓存逻辑是可以重用的。不想写重复代码,所以开发此类;
+         * 大体有两种情况:
+         * 1、集合只加载一次,每次取在集合中获取
+         * 2、每次获取对象判断,不存在,则创建对象补充到缓存中,动态添加
+         */
+        private Func<ParameterT, Dictionary<string, ItemT>> m_LoadAllItems;
+        private Func<ParameterT, Dictionary<string, ItemT>> m_LoadMissItems;
+        private Func<ParameterT, string> m_CreateKey;
+        public CacheItems(Func<ParameterT, Dictionary<string, ItemT>> loadAllItems) : this(loadAllItems, null, null)
+        {
+        }
+        public CacheItems(Func<ParameterT, Dictionary<string, ItemT>> loadAllItems, Func<ParameterT, string> createKey) : this(loadAllItems, null, createKey)
+        {
+        }
+        public CacheItems(Func<ParameterT, Dictionary<string, ItemT>> loadAllItems, Func<ParameterT, Dictionary<string, ItemT>> loadMissItems) : this(loadAllItems, loadMissItems, null)
+        {
+        }
+        public CacheItems(Func<ParameterT, Dictionary<string, ItemT>> loadAllItems, Func<ParameterT, Dictionary<string, ItemT>> loadMissItems, Func<ParameterT, string> createKey)
+        {
+            m_LoadAllItems = loadAllItems;
+            m_LoadMissItems = loadMissItems;
+            m_CreateKey = createKey;
+        }
+        /// <summary>
+        /// 标志数据是否已经加载
+        /// </summary>
+        /// 开发标志位,开发人员自行使用
+        public bool IsLoad { get; private set; }
+        public ItemT GetItem(ParameterT key)
+        {
+            ItemT result = default(ItemT);
+            #region 总条目获取
+            if (!IsLoad && m_LoadAllItems != null)
+            {
+                var allItems = m_LoadAllItems(key);
+                foreach (var item in allItems)
+                {
+                    this[item.Key] = item.Value;
+                }
+                IsLoad = true;
+            }
+            #endregion
+            #region 生成key值
+            string useKey = null;
+            if (m_CreateKey == null)
+            {
+                useKey = key.ToString();
+            }
+            else
+            {
+                useKey = m_CreateKey(key);
+            }
+            #endregion
+
+            #region 获取值
+            if (this.TryGetValue(useKey, out result))
+            {
+                return result;
+            }
+            if (m_LoadMissItems == null)
+            {
+                return result;
+            }
+            #region 加载丢失值重新获取
+            var missItems = m_LoadMissItems(key);
+            foreach (var item in missItems)
+            {
+                this[item.Key] = item.Value;
+            }
+            if (missItems.TryGetValue(useKey, out result))
+            {
+                return result;
+            }
+            #endregion
+            #endregion
+            return result;
+        }
+    }
+}

+ 67 - 0
MBI/SAGA.DotNetUtils/Data/FlagDecorator.cs

@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.DotNetUtils.Data
+{
+    /// <summary>
+    /// 标记装饰类
+    /// </summary>
+    /// <typeparam name="F"></typeparam>
+    /// <typeparam name="D">被装饰类</typeparam>
+    public class FlagDecorator<F, D>
+    {
+        public FlagDecorator()
+        { }
+
+        public FlagDecorator(F f, D d)
+        {
+            Flag = f;
+            Instance = d;
+        }
+        public FlagDecorator(D d)
+        {
+            Instance = d;
+        }
+        public F Flag { get; set; }
+        public D Instance { get; set; }
+        /// <summary>
+        /// 是否处理过
+        /// </summary>
+        public bool Handled { get; set; }
+    }
+    /// <summary>
+    /// 布尔标记
+    /// </summary>
+    /// <typeparam name="D">被装饰类</typeparam>
+    public class BoolFlag<D> : FlagDecorator<bool, D>
+    {
+        public BoolFlag()
+        { }
+
+        public BoolFlag(bool f, D d) : base(f, d)
+        {
+        }
+        public BoolFlag(D d) : base(d)
+        {
+        }
+    }
+    /// <summary>
+    /// 字符串标记
+    /// </summary>
+    /// <typeparam name="D">被装饰类</typeparam>
+    public class StringFlag<D> : FlagDecorator<string, D>
+    {
+        public StringFlag()
+        { }
+
+        public StringFlag(string f, D d) : base(f, d)
+        {
+        }
+        public StringFlag(D d) : base(d)
+        {
+        }
+    }
+}

+ 12 - 3
MBI/SAGA.DotNetUtils/NPOI/NPOIHelper.cs

@@ -358,11 +358,20 @@ namespace SAGA.DotNetUtils.NPOI
                 if (index !=null)
                 {
                     int i = (int) index;
-                    value = row.GetCell(i)?.StringCellValue;
+                    var baseCell = row.GetCell(i);
+                    if (baseCell == null)
+                    {
+                        item.SetValue(model, "");
+                        continue;
+                    }                   
                     //如果读取到的值为null,则判断是否为合并单元格,读取合并单元格的值
-                    if (value.IsNullOrEmpty())
+                    if (baseCell.IsMergedCell)
+                    {
+                        value = row.GetDataCell(i)?.ToString();
+                    }
+                    else
                     {
-                        value = row.GetDataCell(i)?.StringCellValue;
+                        value = row.GetCell(i)?.ToString();
                     }
                     item.SetValue(model, value);
                 }

+ 2 - 0
MBI/SAGA.DotNetUtils/SAGA.DotNetUtils.csproj

@@ -197,6 +197,7 @@
   <ItemGroup>
     <Compile Include="AOP\AopAttribute.cs" />
     <Compile Include="AOP\IAop.cs" />
+    <Compile Include="Cache\CacheItems.cs" />
     <Compile Include="Cache\MemoryCacheHelper.cs" />
     <Compile Include="Component\AllowDisposableSet!1.cs" />
     <Compile Include="Component\ChangedEventArgs.cs" />
@@ -254,6 +255,7 @@
     <Compile Include="Data\EdgesArray\EdgesArrayUtil.cs" />
     <Compile Include="Data\EdgesArray\ForwardStar.cs" />
     <Compile Include="Data\EdgesArray\VisitControl.cs" />
+    <Compile Include="Data\FlagDecorator.cs" />
     <Compile Include="Data\InitAttribute.cs" />
     <Compile Include="Data\InitObejct.cs" />
     <Compile Include="Data\SingleInstance.cs" />

+ 8 - 5
MBI/SAGA.GplotManage/GplotCommand.cs

@@ -5,6 +5,7 @@ using Autodesk.Revit.DB;
 using Autodesk.Revit.UI;
 using SAGA.GplotDrawData;
 using SAGA.GplotManage.UploadRelated;
+using SAGA.GplotRelationComputerManage;
 using SAGA.MBI.Common;
 using SAGA.Models;
 using SAGA.RevitUtils.Extends;
@@ -151,11 +152,13 @@ namespace SAGA.GplotManage
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
-            //var ds = GplotUtil.CreateClient("ChillWaterLoop").GplotCompute.GetUseRelations();
-            //var ds2 = GplotUtil.CreateClient("ChillWaterLoop").GplotCompute.GetValveRelationIds("3901218");
-            //
-            //GplotUtil.CreateClient("ChillWaterLoop").GplotView.Show();
-          
+            //var relationType = RelationTypeManager.GetRelationTypeItem("ChillWaterLoop");
+            //return Result.Succeeded;
+            //SystemComputerHandler handler1 = new SystemComputerHandler();
+            //SystemComputerContext context = new SystemComputerContext();
+            //context.Relations.Add("ChillWaterLoop");
+            //handler1.GetParseData(context);
+            //return Result.Succeeded;
             RoomShowHandler handler = new RoomShowHandler("ChillWaterLoop");
             handler.Show();
             ;

+ 0 - 6
MBI/SAGA.GplotManage/GplotManage/LocalDataUtil.cs

@@ -1,12 +1,6 @@
 using Newtonsoft.Json;
 using SAGA.Models;
-using System;
-using System.Collections.Generic;
 using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
 namespace SAGA.GplotManage
 { 
     public static class LocalDataUtil

+ 48 - 0
MBI/SAGA.GplotRelationComputerManage/Common/AppSetting.cs

@@ -0,0 +1,48 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:AppSetting
+ * 作者:xulisong
+ * 创建时间: 2019/1/9 10:19:12
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 程序相关设置
+    /// </summary>
+    public class AppSetting
+    {
+        static AppSetting()
+        {
+            ViewSuffix = "-saga";
+        }
+        /// <summary>
+        /// 可用视图后缀
+        /// </summary>
+        public  static string ViewSuffix { get; private set; }
+
+        /// <summary>
+        /// 立管开始标志[start]
+        /// </summary>
+        public static string StartFlag { get; private set; } = "start";
+
+        /// <summary>
+        /// 标志族名称[流向指示符]
+        /// </summary>
+        public static string FamilyStartFlag { get; private set; } = "流向指示符|风向箭头";
+        /// <summary>
+        /// 端标志
+        /// </summary>
+        public static string EndFlag { get; private set; } = "外|端";
+        /// <summary>
+        /// 源标志
+        /// </summary>
+        public static string SourceFlag { get; private set; } = "内";
+    }
+}

+ 34 - 0
MBI/SAGA.GplotRelationComputerManage/Common/DataServerUtil.cs

@@ -0,0 +1,34 @@
+using System;
+using SAGA.Models;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 数据读写模块
+    /// </summary>
+    public class DataServerUtil
+    {
+        private static DataServer m_DataServer;
+
+        /// <summary>
+        /// 当前数据服务信息
+        /// </summary>
+        public static DataServer Current
+        {
+            get
+            {
+                if (m_DataServer == null)
+                {
+                    m_DataServer = new DataServer((file) =>
+                    {
+                        var basePath = StaticData.DbDirectory;
+                        TimeVersionFile versionFile = new TimeVersionFile(basePath, file);
+                        return versionFile;
+                    });
+                }
+                return m_DataServer;
+
+            }
+        }
+    }
+}

+ 35 - 2
MBI/SAGA.GplotRelationComputerManage/Common/MBIInfoUtil.cs

@@ -6,6 +6,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using SAGA.MBI.DataArrange;
 
@@ -28,8 +29,7 @@ namespace SAGA.GplotRelationComputerManage
             if (!(fi is FamilyInstance))
             {
                 return useName;
-            }
-            
+            }           
             do
             {
 
@@ -58,5 +58,38 @@ namespace SAGA.GplotRelationComputerManage
 
             return string.Format($"{useName}:{fi.Id.ToString()}");
         }
+
+        /// <summary>
+        /// 标识元素是否是设备
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public static bool IsEquipment(Element element)
+        {
+            if (!(element is FamilyInstance))
+            {
+                return false;
+            }
+            List<BuiltInCategory> categories = new List<BuiltInCategory>();
+            categories.Add(BuiltInCategory.OST_PipeFitting);
+            categories.Add(BuiltInCategory.OST_DuctFitting);
+            if (categories.Any(c => element.Category.Id.IntegerValue == (int)c))
+            {
+                return false;
+            }
+            string familyName = element.GetFamily()?.Name ?? string.Empty;
+            var match = Regex.Match(familyName, @"^(?:((?:[A-Z][A-Z]){2,3})\s*-\s*\S*)");
+            return match.Success;
+        }
+
+        /// <summary>
+        /// 通过标高名称获取楼层名称
+        /// </summary>
+        /// <param name="levelName"></param>
+        /// <returns></returns>
+        public static string GetFloorNameByLevel(string levelName)
+        {
+            return levelName.Replace(AppSetting.ViewSuffix, "");
+        }
     }
 }

+ 40 - 0
MBI/SAGA.GplotRelationComputerManage/Common/PointConverter.cs

@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:PointConverter
+ * 作者:xulisong
+ * 创建时间: 2019/1/9 10:15:17
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Media3D;
+using Autodesk.Revit.DB;
+using SP= System.Windows.Point;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public static class PointConverter
+    {
+        public static Point3D XYZToPoint3D(this XYZ xyz)
+        {
+            return new Point3D(xyz.X, xyz.Y, xyz.Z);
+        }
+
+        public static XYZ Point3DToXYZ(this Point3D point)
+        {
+            return new XYZ(point.X, point.Y, point.Z);
+        }
+        public static SP XYZToPoint(this XYZ xyz)
+        {
+            return new SP(xyz.X, xyz.Y);
+        }
+
+        public static XYZ PointToXYZ(this SP point)
+        {
+            return new XYZ(point.X, point.Y, 0);
+        }
+    }
+}

+ 2 - 2
MBI/SAGA.GplotRelationComputerManage/ComputerPipes.cs

@@ -13,6 +13,7 @@ using System.IO;
 using System.Linq;
 using Autodesk.Revit.DB.Plumbing;
 using Autodesk.Revit.DB;
+using SAGA.MBI.Tools;
 using SAGA.RevitUtils;
 
 namespace SAGA.GplotRelationComputerManage
@@ -58,12 +59,11 @@ namespace SAGA.GplotRelationComputerManage
                     }
                     catch (System.Exception ex)
                     {
-
                         Console.WriteLine(ex.Message);
                     }
                     finally
                     {
-                        doc.Close();
+                        doc.CloseDocSimple();
                     }
                 }
             }

+ 0 - 17
MBI/SAGA.GplotRelationComputerManage/ComputerVerticalPipe.cs

@@ -55,25 +55,8 @@ namespace SAGA.GplotRelationComputerManage
             m_Rooms.TryGetValue(bimId, out RoomItem resultItem);
             return resultItem;
         }
-
-
         #endregion
         #region 空间缓存约束
-        public string GetSpaceDisplay(Space space)
-        {
-            if (space == null)
-                return string.Empty;
-            string bimId = space.GetBimId();
-            var room = GetRoomItem(bimId);
-            string useName = space.Name;
-            if (room != null&&!string.IsNullOrWhiteSpace(room.LocalName))
-            {
-                useName = room.LocalName;
-            }
-            //此类缓存所有空间信息
-            //本地名称为null的话要使用Name
-            return useName;
-        }
         public string GetSpaceDisplay(Space space,out string tip)
         {
             tip = string.Empty;

+ 138 - 0
MBI/SAGA.GplotRelationComputerManage/DataServer/DataServer.cs

@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public class DataServer
+    {
+        protected Func<string, IVersionFile> m_BuilderVersionFile;
+        public DataServer()
+        { }
+        public DataServer(Func<string, IVersionFile> versionFileBuilder)
+        {
+            m_BuilderVersionFile = versionFileBuilder;
+        }      
+        public virtual IVersionFile CreateVersionFile(string fileName)
+        {
+           return m_BuilderVersionFile?.Invoke(fileName);
+        }
+        #region 功能相关类
+        /// <summary>
+        /// 清除指定的文件
+        /// </summary>
+        /// <param name="fileName"></param>
+        public void ClearData(string fileName)
+        {
+            IVersionFile file = CreateVersionFile(fileName);
+            file?.Delete();
+        }
+        /// <summary>
+        /// 清理数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        public void ClearData<T>()
+        {
+            var fileKey = GetFileKey<T>();
+            if (!string.IsNullOrWhiteSpace(fileKey))
+            {
+                ClearData(fileKey);
+            }
+        }
+        public bool SaveData<T>(string fileName, T data)
+        {
+            IVersionFile file = CreateVersionFile(fileName);
+            var settings = new JsonSerializerSettings();
+            string dataStr = JsonConvert.SerializeObject(data, settings);
+            ClearData(fileName);
+            return file.WriteFileContent(dataStr);
+        }
+        /// <summary>
+        /// 根据文件类型或者文件名保存数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="data"></param>
+        public bool SaveData<T>(T data)
+        {
+
+            var fileKey = GetFileKey<T>();
+            if (!string.IsNullOrWhiteSpace(fileKey))
+            {
+                return SaveData<T>(fileKey, data);
+            }
+
+            throw new ArgumentException("未解析到fileKey,请显示传入参数fileKey");
+        }
+        /// <summary>
+        /// 根据文件类型或者文件名获取数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        public T LoadData<T>(string fileName)
+        {
+            IVersionFile file = CreateVersionFile(fileName);
+            var content = file.ReadFileContent();
+            if (!string.IsNullOrWhiteSpace(content))
+            {
+                return JsonConvert.DeserializeObject<T>(content);
+            }
+            return default(T);
+        }
+
+        /// <summary>
+        /// 加载数据
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public T LoadData<T>()
+        {
+            var fileKey = GetFileKey<T>();
+            if (!string.IsNullOrWhiteSpace(fileKey))
+            {
+                return LoadData<T>(fileKey);
+            }
+            return default(T);
+        }
+
+        public bool IsExpired(string fileKey, DateTime dateTime)
+        {
+            var version = CreateVersionFile(fileKey)?.ReadVersion();
+            if (string.IsNullOrEmpty(version))
+            {
+                return true;
+            }
+            var refTime = dateTime.ToString("yyyyMMddHHmmss");
+            return string.Compare(version, refTime) < 0;
+        }
+        public bool IsExpired<T>(DateTime dateTime)
+        {
+            var fileName = DataServer.GetFileKey<T>();
+            return IsExpired(fileName, dateTime);
+
+        } 
+        #endregion
+        /// <summary>
+        /// 获取文件类型key值
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public static string GetFileKey<T>()
+        {
+            var type = typeof(T);
+            FileKeyAttribute fileKey = null;        
+            fileKey = type.GetCustomAttribute<FileKeyAttribute>();
+            if (type.IsGenericType && fileKey == null)
+            {
+                type = type.GetGenericArguments()?.FirstOrDefault();
+                fileKey = type?.GetCustomAttribute<FileKeyAttribute>();
+            }
+            return fileKey?.FileKey;
+        }
+    }
+}

+ 30 - 0
MBI/SAGA.GplotRelationComputerManage/DataServer/FileKeyAttribute.cs

@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:FileKeyAttribute
+ * 作者:xulisong
+ * 创建时间: 2019/1/21 14:23:46
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 文件key值标记
+    /// </summary>
+    public class FileKeyAttribute: Attribute
+    {
+        public string FileKey
+        {
+            get; set;
+        }
+        public FileKeyAttribute(string fileKey)
+        {
+            FileKey = fileKey;
+        }
+    }
+}

+ 30 - 0
MBI/SAGA.GplotRelationComputerManage/DataServer/IVersionFile.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 版本控制文件
+    /// </summary>
+    public interface IVersionFile
+    {
+        string FileKey { get; }
+        string ReadVersion();
+        bool WriteVersion(string version);
+
+        string GetFilePath();
+
+        string ReadFileContent();
+        bool WriteFileContent(string fileContent);
+
+        bool Exists();
+        bool Delete();
+    }
+
+
+}

+ 191 - 0
MBI/SAGA.GplotRelationComputerManage/DataServer/TimeVersionFile.cs

@@ -0,0 +1,191 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:TimeVersionFile
+ * 作者:xulisong
+ * 创建时间: 2019/1/21 14:07:54
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public class TimeVersionFile : IVersionFile
+    {
+        /*
+         * 1、以相对路径下的fileName为键值去处理
+         * 2、文件扩展名名为.20080101120000.vf
+         */
+        public TimeVersionFile(string basePath, string fileKey)
+        {
+            if (string.IsNullOrWhiteSpace(fileKey))
+                throw new ArgumentNullException(nameof(FileKey));
+            RepertoryPath = basePath;
+            FileKey = fileKey;
+        }
+        /// <summary>
+        /// 仓库地址
+        /// </summary>
+        public string RepertoryPath { get; private set; }
+        #region 静态方法
+        /// <summary>
+        /// 无扩展名的文件名称
+        /// </summary>
+        /// <remarks>如:test.txt时,只传入test</remarks>
+        /// <param name="fileName"></param>
+        /// <returns></returns>
+        public static string NewVersionFileName(string fileName)
+        {
+            return string.Format($"{fileName}.{DateTime.Now.ToString("yyyyMMddHHmmss")}.vf");
+        }
+        /// <summary>
+        /// 通过文件名称读取版本号
+        /// </summary>
+        /// <remarks>如:test.20180101112233.vf</remarks>
+        /// <param name="vFileName"></param>
+        /// <returns></returns>
+        public static string ReadFileVersion(string vFileName)
+        {
+            var strArry = vFileName.Split('.');
+            if (strArry.Length > 1)
+            {
+                return strArry[1];
+            }
+            return string.Empty;
+        }
+        #endregion
+
+        #region 私有函数
+        private string GetFileName(string fileKey)
+        {
+            return fileKey;
+        }
+        /// <summary>
+        /// 获取当前文件路径
+        /// </summary>
+        /// <param name="filekey"></param>
+        /// <returns></returns>
+        private string CreateNewPath(string filekey)
+        {
+            //合成新的path
+            var fileName = GetFileName(filekey);
+            return Path.Combine(RepertoryPath, NewVersionFileName(fileName));
+        }
+
+        private string GetCurrentDirectory(string filekey)
+        {
+            var tempPath = Path.Combine(RepertoryPath, GetFileName(filekey));
+            return Path.GetDirectoryName(tempPath);
+        }
+        #endregion
+        #region 实现相关
+
+        /// <summary>
+        /// 文件key值
+        /// </summary>
+        public string FileKey { get; private set; }
+        /// <summary>
+        /// 获取真实存在的路径信息
+        /// </summary>
+        /// <returns></returns>
+        public string GetFilePath()
+        {
+            var directory = GetCurrentDirectory(FileKey);
+            var fileName = GetFileName(FileKey);
+            if (Directory.Exists(directory))
+            {
+                var files = Directory.EnumerateFiles(RepertoryPath, $"{fileName}.*.vf");
+                return files.FirstOrDefault();
+            }
+            return null;
+        }
+        /// <summary>
+        /// 读取版本信息
+        /// </summary>
+        /// <returns></returns>
+        public string ReadVersion()
+        {
+            string filePath = GetFilePath();
+            if (filePath != null)
+                return ReadFileVersion(Path.GetFileName(filePath));
+            return string.Empty;
+        }
+        /// <summary>
+        /// 写入版本信息【文件存在才能写入版本】
+        /// </summary>
+        /// <param name="version"></param>
+        /// <returns></returns>
+        public bool WriteVersion(string version)
+        {
+            //重命名文件名称
+            var filePath = GetFilePath();
+            if (File.Exists(filePath))
+            {
+
+                var fileName = Path.GetFileName(filePath);
+                var strArry = fileName.Split('.');
+                if (strArry.Length > 1)
+                {
+                    strArry[1] = version;
+                }
+                var newFilePath = string.Join(".", strArry);
+                File.Copy(filePath, newFilePath, true);
+                return true;
+            }
+            return false;
+        }
+
+        public string ReadFileContent()
+        {
+            var filePath = GetFilePath();
+            if (File.Exists(filePath))
+            {
+                return File.ReadAllText(filePath);
+            }
+            return string.Empty;
+        }
+
+
+        public bool WriteFileContent(string fileContent)
+        {
+            var newPath = CreateNewPath(FileKey);
+            var directory = Path.GetDirectoryName(newPath);
+            if (!Directory.Exists(directory))
+            {
+                Directory.CreateDirectory(directory);
+            }
+            File.WriteAllText(newPath, fileContent);
+            return true;
+        }
+        /// <summary>
+        /// 判断是否存在
+        /// </summary>
+        /// <returns></returns>
+        public bool Exists()
+        {
+            string filePath = GetFilePath();
+            return File.Exists(filePath);
+        }
+        /// <summary>
+        /// 删除文件
+        /// </summary>
+        /// <returns></returns>
+        public bool Delete()
+        {
+            var directory = GetCurrentDirectory(FileKey);
+            var fileName = GetFileName(FileKey);
+            if (Directory.Exists(directory))
+            {
+                var files = Directory.EnumerateFiles(RepertoryPath, $"{fileName}.*.vf");
+                files.ToList().ForEach(f => File.Delete(f));
+                return true;
+            }
+            return false;
+        }
+        #endregion
+    }
+}

+ 35 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/Data/EdgeItem.cs

@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:EdgeItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/14 10:46:36
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 边类型
+    /// </summary>
+    public class EdgeItem
+    {
+        /// <summary>
+        /// 边类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 边名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 是否有向
+        /// </summary>
+        public bool IsDirected { get; set; }
+    }
+}

+ 107 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/Data/ObjectItem.cs

@@ -0,0 +1,107 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ObjectItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/14 11:39:55
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 对象数据
+    /// </summary>
+    public class ObjectItem
+    {
+        /// <summary>
+        /// 对象类型
+        /// </summary>
+        public string Type { get; set; }
+
+        /// <summary>
+        /// 对象名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+    /// <summary>
+    /// 二元项目
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public class BinaryItem<T>
+    {
+        /*
+         * 如果有Id,可以根据Id比较一次是否包含
+         */
+        public BinaryItem(T first, T second)
+        {
+            First = first;
+            Second = second;
+        }
+        /// <summary>
+        /// 第一个元素
+        /// </summary>
+        public T First { get;private set; }
+        /// <summary>
+        /// 第二个元素
+        /// </summary>
+        public T Second { get; private set; }
+
+        /// <summary>
+        /// 标志关系是否有向
+        /// </summary>
+        public bool IsDirected { get; set; }
+
+        public BinaryMatchResult IsMatch<IT>(IT inputFirst, IT inputSecond, Func<T, IT> select)
+        {
+            var useSelect = select;
+            if (useSelect == null)
+            {
+                throw new ArgumentNullException(nameof(select));
+            }
+
+            var firstT = useSelect(First);
+            var secondT = useSelect(Second);
+            if (firstT.Equals(inputFirst) && secondT.Equals(inputSecond))
+            {
+                return BinaryMatchResult.Syntropy;
+            }
+            else if (firstT.Equals(inputSecond) && secondT.Equals(inputFirst))
+            {
+                return BinaryMatchResult.Opposite;
+            }
+            else
+            {
+                return BinaryMatchResult.None;
+            }
+        }
+        public BinaryMatchResult IsMatch(T inputFirst, T inputSecond)
+        {
+            return IsMatch<T>(inputFirst, inputSecond, (s) => s);
+        }
+    }
+
+    public enum BinaryMatchResult
+    {
+        /// <summary>
+        /// 未匹配
+        /// </summary>
+        [Description("未匹配")]
+        None=0,
+        /// <summary>
+        /// 同向
+        /// </summary>
+        [Description("同向")]
+        Syntropy,
+        /// <summary>
+        /// 反向
+        /// </summary>
+        [Description("反向")]
+        Opposite,
+    }
+}

+ 56 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/Data/RelationItem.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 关系类型设定
+    /// </summary>
+    public class RelationItem
+    {
+        public RelationItem()
+        {
+            EdgeTypes = new List<EdgeItem>();
+            Objects = new List<ObjectItem>();
+            Systems = new List<SystemItem>();
+            ObjectRelations = new List<BinaryItem<ObjectItem>>();
+        }
+        #region 属性相关维护
+        /// <summary>
+        /// 关系类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 关系名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 边信息
+        /// </summary>
+        public List<EdgeItem> EdgeTypes { get;private set; }
+
+        #region 关联系统
+        /// <summary>
+        /// 关联系统信息
+        /// </summary>
+        public List<SystemItem> Systems { get;private set; }
+        /// <summary>
+        /// 关联系统类型[水管|风管]
+        /// </summary>
+        public SystemType SystemType { get; set; }
+        #endregion
+        /// <summary>
+        /// 对象集合
+        /// </summary>
+        public List<ObjectItem> Objects { get;private set; }
+        /// <summary>
+        /// 对象关系集合【辅助确定关系】
+        /// </summary>
+        public List<BinaryItem<ObjectItem>> ObjectRelations { get;private set; } 
+        #endregion
+    }
+
+}

+ 69 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/Data/SystemItem.cs

@@ -0,0 +1,69 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/14 11:11:46
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 关联系统相关配置
+    /// </summary>
+    public class SystemItem
+    {
+        public SystemItem()
+        {
+            ContainEdgeTypes = new List<string>();
+        }
+        /// <summary>
+        /// 系统名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 流向类型定义
+        /// </summary>
+        public FlowType FlowType { get; set; }
+        /// <summary>
+        /// 包含的边类型
+        /// </summary>
+        public List<string> ContainEdgeTypes { get; private set; }
+        /// <summary>
+        /// 判断是否和输入系统类型匹配
+        /// </summary>
+        /// <param name="inputSystemName"></param>
+        /// <returns></returns>
+        public bool IsMatch(string inputSystemName)
+        {
+            return inputSystemName.Contains(Name);
+        }
+    }
+    /// <summary>
+    /// 流向类型定义
+    /// </summary>
+    public enum FlowType
+    {
+        [Description("未定义")]
+        Undefine,
+        [Description("流入")]
+        In,
+        [Description("流出")]
+        Out,
+    }
+
+    public enum SystemType
+    {
+        [Description("管道系统")]
+        Pipe,
+        [Description("风管系统")]
+        Duct,
+    }
+}

+ 207 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/RelationTypeManager.cs

@@ -0,0 +1,207 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.DotNetUtils;
+using SAGA.DotNetUtils.NPOI;
+using SAGA.Models;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 关联类型管理
+    /// </summary>
+    public class RelationTypeManager
+    {
+        //暂时不用字典
+        public static List<RelationItem> Items { get; private set; }
+        static RelationTypeManager()
+        {
+            try
+            {
+                InitItems();
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+        #region 私有方法
+        private static void InitItems()
+        {
+            List<RelationItem> items = new List<RelationItem>();
+            string file = StaticData.GdRelationship;
+            var relationInfos = NPOIHelper.ConvertExcelSheetToModel<RelationRow>(file);
+            var useRelationInfos = relationInfos.Where(c => !string.IsNullOrEmpty(c.RelationshipType));
+            var group = useRelationInfos.GroupBy(c => c.RelationshipType);
+            foreach (var item in group)
+            {
+                var relationItem = new RelationItem();
+                relationItem.Type = item.Key;
+                var childItems = item.ToList();
+                var firstItem = childItems[0];
+                relationItem.Name = firstItem.RelationName;
+                #region 遍历边类型
+                foreach (var child in childItems)
+                {
+                    EdgeItem edgeItem = new EdgeItem();
+                    edgeItem.Type = child.EdgeType;
+                    edgeItem.Name = child.EdgeName;
+                    edgeItem.IsDirected = "1".Equals(child.EdgeDirection);
+                    relationItem.EdgeTypes.Add(edgeItem);
+                }
+                #endregion
+
+                #region 对象相关处理
+                var strObjects = firstItem.Objects;
+                ParseObjects(relationItem, strObjects);
+                #endregion
+
+                #region 系统相关处理
+                var strSystem = firstItem.Systems;
+                ParseSystems(relationItem, strSystem);
+                #endregion
+
+                items.Add(relationItem);
+            }
+
+            Items = items;
+        }
+        /// <summary>
+        /// 解析对象数据
+        /// </summary>
+        /// <param name="item"></param>
+        /// <param name="strObject"></param>
+        private static void ParseObjects(RelationItem item, string strObject)
+        {
+            #region 描述
+            /*
+                 * 1,object以;或->分割
+                 * 2,对象类型与名称以 -划分
+                 * 3,如果两个对象之间是→,则表示对象关系中,应该是描述的关系
+                 *例子:高压开关柜-TDHS→直流屏-TDDS;
+                 */
+            #endregion
+            if (string.IsNullOrEmpty(strObject))
+            {
+                return;
+            }
+
+            List<ObjectItem> objectIems = new List<ObjectItem>();
+            List<BinaryItem<ObjectItem>> relationItems = new List<BinaryItem<ObjectItem>>();
+            #region 核心解析
+            var objectArrays = strObject.Split(';');
+            foreach (var objectArray in objectArrays)
+            {
+                List<ObjectItem> useObjects = new List<ObjectItem>();
+                List<BinaryItem<ObjectItem>> useRelations = new List<BinaryItem<ObjectItem>>();
+                var singleObjects = objectArray.Split('→');
+                foreach (var singleObject in singleObjects)
+                {
+                    ObjectItem objectIem = new ObjectItem();
+                    var propertyArray = singleObject.Split('-');
+                    if (propertyArray.Length == 1)
+                    {
+                        objectIem.Type = propertyArray[0].Trim();
+                        objectIem.Name = propertyArray[0].Trim();
+                    }
+                    else if (propertyArray.Length == 2)
+                    {
+
+                        objectIem.Type = propertyArray[1].Trim();
+                        objectIem.Name = propertyArray[0].Trim();
+                    }
+
+                    useObjects.Add(objectIem);
+                }
+
+                for (int i = 1; i < useObjects.Count; i++)
+                {
+                    BinaryItem<ObjectItem> relationItem = new BinaryItem<ObjectItem>(useObjects[i - 1], useObjects[i]);
+                    useRelations.Add(relationItem);
+                }
+
+                objectIems.AddRange(useObjects);
+                relationItems.AddRange(useRelations);
+            } 
+            #endregion
+            item.Objects.AddRange(objectIems);
+            item.ObjectRelations.AddRange(relationItems);
+
+        }
+        /// <summary>
+        /// 解析对象系统类型
+        /// </summary>
+        /// <param name="item"></param>
+        /// <param name="strSystem">系统字符串</param>
+        private static void ParseSystems(RelationItem item, string strSystem)
+        {
+            #region 描述
+                /*
+                * 1,系统对象使用;分割
+                * 2,系统以标志信息开始的流向,1,0,-1;
+                * 3,系统关联的边类型子集
+                 * 例子:系统名称1|1|1,2,3
+                */ 
+            #endregion
+            if (string.IsNullOrEmpty(strSystem))
+            {
+                return;
+            }
+            #region 核心解析
+            List<SystemItem> systemIems = new List<SystemItem>();
+            var objectArrays = strSystem.Split(';');
+            foreach (var objectArray in objectArrays)
+            {
+                SystemItem useSystem = new SystemItem();
+                var systemProperties = objectArray.Split('|');
+                for (int i = 0; i < systemProperties.Length; i++)
+                {
+                    SetSystemProperty(useSystem, i, systemProperties[i]);
+                }
+                systemIems.Add(useSystem);
+            }
+            #endregion
+
+            item.Systems.AddRange(systemIems);
+        }
+
+        private static void SetSystemProperty(SystemItem system, int index, string useValue)
+        {
+            switch (index)
+            {
+                case 0:
+                    system.Name = useValue.Trim();
+                    break;
+                case 1:
+                    #region 动态解析枚举
+                    system.FlowType = FlowType.Undefine;
+                    if ("-1" == useValue)
+                    {
+                        system.FlowType = FlowType.Out;
+                    }
+                    else if ("1" == useValue)
+                    {
+                        system.FlowType = FlowType.In;
+                    } 
+                    #endregion
+                    break;
+                case 2:
+                    system.ContainEdgeTypes.AddRange(useValue.Split(',').Select(c => c.Trim()));
+                    break;
+            }
+        }
+        #endregion
+
+        /// <summary>
+        /// 获取指定名称图类型
+        /// </summary>
+        /// <param name="relationType"></param>
+        /// <returns></returns>
+        public static RelationItem GetRelationTypeItem(string relationType)
+        {
+            return Items.FirstOrDefault(c => c.Type == relationType);
+        }
+    }
+}

+ 53 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/RelationTypeShell.cs

@@ -0,0 +1,53 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:RelationTypeShell
+ * 作者:xulisong
+ * 创建时间: 2019/1/15 17:28:03
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 关系类型操作
+    /// </summary>
+    public class RelationTypeShell
+    {
+        public RelationItem RelationItem { get; private set; }
+        public RelationTypeShell(RelationItem relationItem)
+        {
+            RelationItem = relationItem ?? throw new ArgumentNullException(nameof(relationItem));
+        }
+        /// <summary>
+        /// 系统是否匹配
+        /// </summary>
+        /// <param name="systemName"></param>
+        /// <returns></returns>
+        public bool IsMatchSystem(string systemName)
+        {
+            return RelationItem.Systems.Any(c => c.IsMatch(systemName));
+        }
+        /// <summary>
+        /// 对象是否匹配
+        /// </summary>
+        /// <param name="equipmentCategory"></param>
+        /// <returns></returns>
+        public bool IsMatchObject(string equipmentCategory)
+        {
+            return RelationItem.Objects.Any(c => c.Type== equipmentCategory);
+        }
+        /// <summary>
+        /// 是否是水系统
+        /// </summary>
+        /// <returns></returns>
+        public bool IsPipeSystem()
+        {
+            return RelationItem.SystemType == SystemType.Pipe;
+        }
+    }
+}

+ 12 - 0
MBI/SAGA.GplotRelationComputerManage/RelationType/read.txt

@@ -0,0 +1,12 @@
+后续操作中,有过多的逻辑判断依赖于关系类型的系统判断。
+将读取excel的功能封装成一个有用的模块;
+
+关联系统:
+系统名称-1。对应方向;
+方向描述:由立管,或者标记阀门,为基准。以源端为起点,以末端为终点的有向确认方向,
+-1,0,1三个取值,0代表没有方向;
+系统类型中关联变类型的子集
+
+连接对象:
+所有连接对象的集合;
+体现连接对象之间的关系对

+ 29 - 3
MBI/SAGA.GplotRelationComputerManage/SAGA.GplotRelationComputerManage.csproj

@@ -82,7 +82,10 @@
     <Compile Include="ColdRoom\EquipmentItem.cs" />
     <Compile Include="ColdRoom\VectorExtension.cs" />
     <Compile Include="Command.cs" />
+    <Compile Include="Common\AppSetting.cs" />
+    <Compile Include="Common\DataServerUtil.cs" />
     <Compile Include="Common\MBIInfoUtil.cs" />
+    <Compile Include="Common\PointConverter.cs" />
     <Compile Include="ComputerPipes.cs" />
     <Compile Include="ComputerVerticalPipe.cs" />
     <Compile Include="ComputerWalls\ComputerWallsData.cs" />
@@ -90,6 +93,10 @@
     <Compile Include="ComputerWalls\WallOperationFactory.cs" />
     <Compile Include="ComputerWalls\WallRelation.cs" />
     <Compile Include="ComputerWalls\WrapperedWall.cs" />
+    <Compile Include="DataServer\DataServer.cs" />
+    <Compile Include="DataServer\FileKeyAttribute.cs" />
+    <Compile Include="DataServer\IVersionFile.cs" />
+    <Compile Include="DataServer\TimeVersionFile.cs" />
     <Compile Include="LvSpace.cs" />
     <Compile Include="PowerDistribution\Common\DataNodeUtil.cs" />
     <Compile Include="PowerDistribution\Common\PowerComputerContext.cs" />
@@ -100,7 +107,12 @@
     <Compile Include="PumpEnd\DuctTerminalBll.cs" />
     <Compile Include="ReadSpaceCommand.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="RelationshipTools.cs" />
+    <Compile Include="RelationType\Data\EdgeItem.cs" />
+    <Compile Include="RelationType\Data\ObjectItem.cs" />
+    <Compile Include="RelationType\Data\RelationItem.cs" />
+    <Compile Include="RelationType\Data\SystemItem.cs" />
+    <Compile Include="RelationType\RelationTypeManager.cs" />
+    <Compile Include="RelationType\RelationTypeShell.cs" />
     <Compile Include="RevitModelPath.cs" />
     <Compile Include="RevitSystemParse\GplotOptions.cs" />
     <Compile Include="RevitSystemParse\MepExtension.cs" />
@@ -114,9 +126,21 @@
     <Compile Include="SpaceRelation\SpaceComputerContext.cs" />
     <Compile Include="SpaceRelation\SpaceComputerHandler.cs" />
     <Compile Include="SpaceRelation\SpaceComputerManager.cs" />
+    <Compile Include="SystemRelation\Common\PointItemType.cs" />
     <Compile Include="SystemRelation\Common\SystemCalcUtil.cs" />
-    <Compile Include="SystemRelation\FloorSystemItems.cs" />
+    <Compile Include="SystemRelation\Common\SystemParseManager.cs" />
+    <Compile Include="SystemRelation\Data\BinaryRelationItem.cs" />
+    <Compile Include="SystemRelation\Data\EquipmentNode.cs" />
+    <Compile Include="SystemRelation\Data\SetRelationItem.cs" />
+    <Compile Include="SystemRelation\Data\SystemCurveItem.cs" />
+    <Compile Include="SystemRelation\Data\SystemDrawItems.cs" />
+    <Compile Include="SystemRelation\Data\SystemPointItem.cs" />
+    <Compile Include="SystemRelation\FloorSystemItem.cs" />
+    <Compile Include="SystemRelation\ServerData\FloorDrawRecord.cs" />
+    <Compile Include="SystemRelation\ServerData\FloorRecord.cs" />
+    <Compile Include="SystemRelation\ServerData\FloorRelationRecord.cs" />
     <Compile Include="SystemRelation\SystemComputerContext.cs" />
+    <Compile Include="SystemRelation\SystemComputerHandler.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\SAGA.GplotDrawData\SAGA.GplotDrawData.csproj">
@@ -150,6 +174,8 @@
       <SubType>Designer</SubType>
     </None>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <Content Include="RelationType\read.txt" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 31 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/PointItemType.cs

@@ -0,0 +1,31 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:PointItemType
+ * 作者:xulisong
+ * 创建时间: 2019/1/11 11:48:52
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+   /// <summary>
+   /// PointItem预制类型
+   /// </summary>
+    public enum PointItemType
+    {
+        [Description("设备")]
+        Equipment,
+        [Description("立管")]
+        StandPipe,
+        [Description("空间")]
+        Space,
+        [Description("开始阀门")]
+        StartValve
+    }
+}

+ 100 - 4
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/SystemCalcUtil.cs

@@ -8,12 +8,19 @@
 using Autodesk.Revit.DB;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using SAGA.DotNetUtils.Cache;
+using SAGA.MBI.RequestData;
+using SAGA.Models;
 using SAGA.RevitUtils.Extends;
+using MBIEquipItem = SAGA.Models.EquipmentItem;
 
-namespace SAGA.GplotRelationComputerManage.SystemRelation.Common
+namespace SAGA.GplotRelationComputerManage
 {
     /// <summary>
     /// 系统计算相关
@@ -25,13 +32,102 @@ namespace SAGA.GplotRelationComputerManage.SystemRelation.Common
         /// </summary>
         /// <param name="element"></param>
         /// <returns></returns>
-        public bool IsStart(Element element)
+        public static bool IsStart(Element element)
         {
            if (element is FamilyInstance)
            {
-               return element.GetFamily()?.Name == "流向指示符";
+               var name = element.GetFamily().Name;
+               return Regex.IsMatch(name, AppSetting.FamilyStartFlag);
            }
-           return element.GetParameterString(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS) == "start";
+           return element.GetParameterString(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS) == AppSetting.StartFlag;
+        }
+
+        /// <summary>
+        /// 创建房间缓冲集合
+        /// </summary>
+        /// <returns></returns>
+        public static CacheItems<string,RoomItem> CreateRoomItems()
+        {
+            CacheItems<string, RoomItem> items = new CacheItems<string, RoomItem>((s) =>
+            {
+                var rooms = new Dictionary<string, RoomItem>();
+                var str = new string[] {MBIBuiltInCategory.Si};
+                List<JObject> datas = CommonConvert.QueryObjectInfoByTypes(str);
+                foreach (var data in datas)
+                {
+                    var roomItem = MBIItemFactory.Create<RoomItem>(data);
+                    rooms[roomItem.BimId] = roomItem;
+                }
+
+                return rooms;
+            });
+            return items;
+        }
+        /// <summary>
+        /// 创建楼层缓冲集合
+        /// </summary>
+        /// <returns></returns>
+        public static CacheItems<string, FloorSystemItem> CreateFloorItems()
+        {
+            CacheItems<string, FloorSystemItem> items = new CacheItems<string, FloorSystemItem>(null, (path) =>
+            {
+                var floorId = Path.GetFileNameWithoutExtension(path);
+                Dictionary<string, FloorSystemItem> miss = new Dictionary<string, FloorSystemItem>();
+                if (File.Exists(path))
+                {
+                    var uiApp = ExternalDataWrapper.Current.UiApp.Application;
+                    var doc = uiApp.OpenDocumentFile(path);
+                    var floor = new FloorSystemItem(doc);
+                    miss[floorId] = floor;
+                }
+
+                return miss;
+            }, Path.GetFileNameWithoutExtension);
+            return items;
+        }
+
+        /// <summary>
+        /// 创建关系类型壳对象
+        /// </summary>
+        /// <returns></returns>
+        public static CacheItems<string, RelationTypeShell> CreateRelationShellItems()
+        {
+            CacheItems<string, RelationTypeShell> items = new CacheItems<string, RelationTypeShell>((s) =>
+            {
+                var shells = new Dictionary<string, RelationTypeShell>();
+                foreach (var relationItem in RelationTypeManager.Items)
+                {
+                    shells[relationItem.Type] = new RelationTypeShell(relationItem);
+                }
+                return shells;
+            });
+            return items;
+        }
+
+        /// <summary>
+        /// 创建设备缓存对象
+        /// </summary>
+        /// <returns></returns>
+        public static CacheItems<string, MBIEquipItem> CreateEquipmentItems()
+        {
+            CacheItems<string, MBIEquipItem> items = new CacheItems<string, MBIEquipItem>((s) =>
+            {
+                var equipmentItems = new Dictionary<string, MBIEquipItem>();
+                var types = new string[] { MBIBuiltInCategory.Eq };
+                List<JObject> equipDatas = CommonConvert.QueryObjectInfoByTypes(types);
+                foreach (var jobject in equipDatas)
+                {
+                    var item = MBIItemFactory.Create<MBIEquipItem>(jobject);
+                    if (item != null && string.IsNullOrWhiteSpace(item.BimId))
+                    {
+                        equipmentItems[item.BimId]= item;
+                    }
+                }
+           
+                return equipmentItems;
+            });
+            return items;
+          
         }
     }
 }

+ 370 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Common/SystemParseManager.cs

@@ -0,0 +1,370 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemParseManager
+ * 作者:xulisong
+ * 创建时间: 2019/1/10 14:34:23
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using Autodesk.Revit.DB.Plumbing;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 系统解析管理
+    /// </summary>
+    public class SystemParseManager
+    {
+        #region 解析管路系统数据
+        #region 通用基础方法
+        /// <summary>
+        /// 创建树节点
+        /// </summary>
+        /// <param name="startElement"></param>
+        /// <param name="startConnector"></param>
+        /// <param name="predicateEnd"></param>
+        /// <returns></returns>
+        public static ElementTreeNode CreateTreeNode(Element startElement, Connector startConnector,
+            Predicate<Element> predicateEnd)
+        {
+            ElementTreeNode node = new ElementTreeNode();
+            node.Current = startElement;
+            List<ElementTreeNode> reference = new List<ElementTreeNode>();
+            reference.Add(node);
+            for (int i = 0; i < reference.Count; i++)
+            {
+                var baseNode = reference[i];
+                List<Connector> connectors;
+                if (i == 0 && startConnector != null)
+                {
+                    connectors = new List<Connector> { startConnector };
+                }
+                else
+                {
+                    connectors = baseNode.Current.GetAllConnectors().ToList();
+                }
+                foreach (var connector in connectors)
+                {
+                    if (connector.Searchable())
+                    {
+                        var refConnectors = connector.GetReferenceConnectors()
+                            .Where(c => ConnectorType.Physical.HasFlag(c.ConnectorType)).ToList();
+                        foreach (var refConnector in refConnectors)
+                        {
+                            var refElement = refConnector.Owner;
+                            ElementTreeNode refNode = new ElementTreeNode();
+                            refNode.Current = refElement;
+                            refNode.StartLocation = refConnector.Origin;
+                            baseNode.Nodes.Add(refNode);
+                            if (predicateEnd != null && predicateEnd(refElement))
+                            {
+                                continue;
+                            }
+                            if (reference.All(e => e.Current.Id.IntegerValue != refElement.Id.IntegerValue))
+                            {
+                                reference.Add(refNode);
+                            }
+                        }
+                    }
+                }
+            }
+            return node;
+        }
+        #endregion
+
+        /// <summary>
+        /// 构件系统连接节点
+        /// </summary>
+        /// <param name="etn">开始元素</param>
+        /// <param name="domain"></param>
+        /// <param name="endConditon">遍历中断条件,遇到指定条件的管道则停止遍历</param>
+        /// <returns>树形节点中包好的Id信息</returns>
+        public static List<int> BuildSystemNode(ElementTreeNode etn, Domain domain, Func<MEPCurve, bool> endConditon)
+        {
+            List<int> useIds = new List<int>();
+            etn.GetAllNodes().ForEach(n =>
+            {
+                if (!n.IsLeaf&&n.Current != null)
+                {
+                    useIds.Add(n.Current.Id.IntegerValue);
+                }
+            });
+            var leaves = etn.GetLeaves();
+            foreach (var elementTreeNode in leaves)
+            {
+                BuildSystemNode(elementTreeNode, domain, useIds, endConditon);
+            }        
+            return useIds;
+        }
+        private static void BuildSystemNode(ElementTreeNode etn, Domain domain, List<int> useIds, Func<MEPCurve, bool> endConditon)
+        {
+            var useElement = etn.Current;
+            #region 预判退出
+            if (useElement == null)
+            {
+                return;
+            }
+            if (useIds.Any(id => id == useElement.Id.IntegerValue))
+            {
+                return;
+            }
+            #endregion
+
+            useIds.Add(useElement.Id.IntegerValue);
+            var connectors = useElement.GetConnectors(domain);
+            foreach (var baseConnector in connectors)
+            {
+                if (!baseConnector.Searchable())
+                    continue;
+                var refConnectors = baseConnector.GetReferenceConnectors()
+                    .Where(c => ConnectorType.Physical.HasFlag(c.ConnectorType)).ToList();
+                foreach (var refConnector in refConnectors)
+                {
+                    var refElement = refConnector.Owner;
+                    if (useIds.Any(id => id == refElement.Id.IntegerValue))
+                    {
+                        continue;
+                    }
+                    //初始化当前节点,未必一定加入集合,为了下面代码书写方便,先进性初始化
+                    ElementTreeNode currentNode = new ElementTreeNode()
+                    {
+                        Current = refElement,
+                        StartLocation = refConnector.Origin
+                    };
+                    if (refElement is MEPCurve mepCurve)
+                    {
+                        //优先判定系统,再进行立管相关逻辑的处理;如果系统不兼容则直接退出遍历
+                        //var systemName=mepCurve.GetSystemTypeName();
+                        if (endConditon != null && endConditon(mepCurve))
+                        {
+                            continue;
+                        }
+                        if (SystemCalcUtil.IsStart(mepCurve))
+                        {
+                            currentNode.ElementTypeName = AcType.MarkStandPipe;
+                            etn.AddChild(currentNode);
+                            useIds.Add(refElement.Id.IntegerValue);
+                            continue;
+                        }
+                    }
+                    else if (refElement is FamilyInstance fi)
+                    {
+                        //非管线,遇到结束标志,加入当前子节点,但不在进行递归;
+                        if (SystemCalcUtil.IsStart(fi))
+                        {
+                            currentNode.ElementTypeName = AcType.Valve;
+                            etn.AddChild(currentNode);
+                            useIds.Add(refElement.Id.IntegerValue);
+                            continue;
+                        }
+                    }
+                    //useIds的控制:跳出时,直接加入UseIds。继续遍历的,在遍历函数中加入
+                    etn.AddChild(currentNode);
+                    BuildSystemNode(currentNode, domain, useIds, endConditon);
+
+                }
+            }
+        }
+        #endregion
+
+
+        #region 创建绘图数据相关
+        /// <summary>
+        /// 构件绘图数据
+        /// </summary>
+        /// <param name="etn"></param>
+        /// <returns></returns>
+        public static SystemDrawItems CreateDrawing(ElementTreeNode etn)
+        {
+            #region 描述
+            /*
+             *读取几何信息
+             * 1、管道,管件直接按connector连线获取。
+             * 2、设备,可能出现多个connector,确定有效的连线;
+             * 最终:如果是管道,通过本身的connector生成线。如果是familyInstance通过定位点连接,父节点和子节点
+             * 3、具体名字相关内容,后续操作中添加
+             */
+            #endregion
+            List<SystemCurveItem> curveItems = new List<SystemCurveItem>();
+            List<SystemPointItem> pointItems = new List<SystemPointItem>();
+            Queue<ElementTreeNode> nodeQueue = new Queue<ElementTreeNode>() ;
+            nodeQueue.Enqueue(etn);
+            while (nodeQueue.Any())
+            {
+                #region 控制验证
+                var currentNode = nodeQueue.Dequeue();
+                if (currentNode == null)
+                    continue;
+                var element = currentNode.Current;
+                if (element == null)
+                    continue;
+                #endregion
+                if (element is MEPCurve mepCurve)
+                {
+                    #region 联通线处理
+                    Curve curve = mepCurve.GetCurve();
+                    var xyzs = curve.Tessellate().Select(xyz => xyz.XYZToPoint());
+                    SystemCurveItem curveItem = new SystemCurveItem();
+                    curveItem.Points.AddRange(xyzs.ToList());
+                    curveItem.RefId = element.Id.IntegerValue;
+                    curveItems.Add(curveItem);
+                    #endregion
+                    #region 点信息处理
+
+                    if (SystemCalcUtil.IsStart(mepCurve))
+                    {
+                        SystemPointItem point = new SystemPointItem();
+                        point.Point = mepCurve.GetCurve().StartPoint().XYZToPoint();
+                        point.RefId = mepCurve.Id.IntegerValue;
+                        point.IsVirtual = true;
+                        point.EquipmentType = PointItemType.StandPipe.ToString();
+                        pointItems.Add(point);
+                    } 
+                    #endregion
+                }
+                else if (element is FamilyInstance fiEq)
+                {
+                    #region 获取引用点
+                    List<XYZ> usePoints = new List<XYZ>();
+                    if (currentNode.StartLocation != null)
+                    {
+                        usePoints.Add(currentNode.StartLocation);
+                    }
+                    foreach (ElementTreeNode childNode in currentNode.Nodes)
+                    {
+                        var usePoint = childNode.StartLocation;
+                        if (usePoint != null)
+                        {
+                            usePoints.Add(usePoint);
+                        }
+                    }
+                    #endregion
+                    var location = element.GetBoxCenter().XYZToPoint();
+                    #region  根据定位点并创建线条
+
+                    foreach (var usePoint in usePoints)
+                    {
+                        SystemCurveItem curveItem = new SystemCurveItem();
+                        curveItem.Points.Add(location);
+                        curveItem.Points.Add(usePoint.XYZToPoint());
+                        curveItem.RefId = element.Id.IntegerValue;
+                        curveItems.Add(curveItem);
+                    }
+                    #endregion
+
+                    #region 判断是否是设备
+                    //先初始化不一定加入
+                    SystemPointItem point = new SystemPointItem();
+                    point.Point = location;
+                    point.RefId = fiEq.Id.IntegerValue;
+                    point.BimId = element.GetBimId();
+                    if (MBIInfoUtil.IsEquipment(fiEq))
+                    {
+                        point.Name = string.Empty;
+                        point.EquipmentType = PointItemType.Equipment.ToString();
+                        pointItems.Add(point);
+                    }
+                    else if (SystemCalcUtil.IsStart(fiEq))
+                    {
+                        point.Name = string.Empty;
+                        point.EquipmentType = PointItemType.StartValve.ToString(); ;
+                        point.IsVirtual = true;
+                        pointItems.Add(point);
+                    }
+                    #endregion
+                }
+                else if (element is Space)
+                {
+                    SystemPointItem point = new SystemPointItem();
+                    point.Point = element.GetLocationPoint().XYZToPoint();
+                    point.RefId = element.Id.IntegerValue;
+                    point.EquipmentType = PointItemType.Space.ToString();
+                    point.IsVirtual = true;
+                    pointItems.Add(point);
+                }
+                currentNode.Nodes.ForEach(e => nodeQueue.Enqueue(e));
+            }
+
+            SystemDrawItems drawItems = new SystemDrawItems();
+            drawItems.Curves = curveItems;
+            drawItems.Points = pointItems;
+            return drawItems;
+        }
+        #endregion
+
+        #region 创建关系数据相关
+        public static List<EquipmentNode> CreateRelation(ElementTreeNode etn)
+        {
+            #region 描述
+            /*
+             * 1、将树形结构初步处理,修剪成存留设备之间的关系
+             */
+            #endregion
+
+            return ConvertEquipmentNodes(etn);
+        }
+
+        /// <summary>
+        /// 将elment树转换成设备节点类
+        /// </summary>
+        /// <param name="etn"></param>
+        /// <returns></returns>
+        private static List<EquipmentNode> ConvertEquipmentNodes(ElementTreeNode etn)
+        {
+            List<EquipmentNode> nodes = new List<EquipmentNode>();
+            if (TryGetNode(etn.Current,out EquipmentNode outNode))
+            {
+                nodes.Add(outNode);
+                return nodes;
+            }
+            foreach (var elementTreeNode in etn.Nodes)
+            {
+                nodes.AddRange(ConvertEquipmentNodes(elementTreeNode));
+            }
+            return nodes;
+        }
+        /// <summary>
+        /// 获取element对应节点
+        /// </summary>
+        /// <param name="element">输入element</param>
+        /// <param name="outNode">成功获取时,node真实值</param>
+        /// <returns>成功获取</returns>
+        private static bool TryGetNode(Element element,out EquipmentNode outNode)
+        {
+            bool flag = false;
+            EquipmentNode node = new EquipmentNode();
+            node.RevitId = element.Id.IntegerValue;
+            node.BimId = element.GetBimId();
+            if (element is Space space)
+            {
+                node.Category = PointItemType.Space.ToString();
+            }
+            else if (element is Pipe&& SystemCalcUtil.IsStart(element))
+            {
+                node.Category = PointItemType.StandPipe.ToString();
+            }
+            else if (element is FamilyInstance)
+            {
+                if (MBIInfoUtil.IsEquipment(element))
+                {
+                    node.Category = PointItemType.Equipment.ToString();
+                }
+                else if (SystemCalcUtil.IsStart(element))
+                {
+                    node.Category = PointItemType.StartValve.ToString();
+                }
+            }
+            flag = !string.IsNullOrEmpty(node.Category);
+            outNode = flag ? node : null;
+            return flag;
+        }
+        #endregion
+    }
+}

+ 30 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/BinaryRelationItem.cs

@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:BinaryRelationItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/22 16:38:20
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 二元关系类
+    /// </summary>
+    public class BinaryRelationItem
+    {
+        /// <summary>
+        /// 开始节点
+        /// </summary>
+        public EquipmentNode From { get; set; }
+        /// <summary>
+        /// 结束节点
+        /// </summary>
+        public EquipmentNode To { get; set; }
+    }
+}

+ 39 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/EquipmentNode.cs

@@ -0,0 +1,39 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:EquipmentNode
+ * 作者:xulisong
+ * 创建时间: 2019/1/11 15:32:30
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using SAGA.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 设备节点
+    /// </summary>
+    public class EquipmentNode:TNode<EquipmentNode>
+    {
+        /// <summary>
+        /// 物理世界Id
+        /// </summary>
+        public string MbiId{ get; set; }
+        /// <summary>
+        /// BimId带楼层的Id
+        /// </summary>
+        public string BimId { get; set; }
+        /// <summary>
+        /// revit模型中Id
+        /// </summary>
+        public int RevitId { get; set; }
+        /// <summary>
+        /// 设备分类
+        /// </summary>
+        public string Category { get; set; }
+    }
+}

+ 25 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SetRelationItem.cs

@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SetRelationItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/22 16:45:42
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 集合关系类,其中的元素两两进行相关
+    /// </summary>
+    public class SetRelationItem :List<EquipmentNode>
+    {
+        /*
+         * 目前,将立管之间的关系整理成集合关系
+         */
+    }
+}

+ 56 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemCurveItem.cs

@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemCurveItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/10 11:43:53
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.DB;
+using SAGA.RevitUtils.MEP;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SP= System.Windows.Point;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 【系统】管线描述
+    /// </summary>
+    public class SystemCurveItem
+    {
+        public SystemCurveItem()
+        {
+            Points = new List<SP>();
+        }
+        /// <summary>
+        /// 关联点位信息
+        /// </summary>
+        public List<SP> Points { get;private  set; }
+        /// <summary>
+        /// 关联Id
+        /// </summary>
+        public int RefId { get; set; }
+        /// <summary>
+        /// 创建线展示信息
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="domain"></param>
+        /// <returns></returns>
+        public static List<SystemCurveItem> CreateCurveItems(Element element,Domain domain)
+        {
+            List<SystemCurveItem> items = new List<SystemCurveItem>();
+            if (element == null)
+                return items;
+            var connectors = element.GetConnectors(domain);
+            //XYZ location=element.GetMBILocation()
+            foreach (var connector in connectors)
+            {
+                
+            }
+            return items;
+        }
+    }
+}

+ 30 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemDrawItems.cs

@@ -0,0 +1,30 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemDrawItems
+ * 作者:xulisong
+ * 创建时间: 2019/1/11 15:16:55
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 系统绘图集合
+    /// </summary>
+    public class SystemDrawItems
+    {
+        /// <summary>
+        /// 关联线集合
+        /// </summary>
+        public List<SystemCurveItem> Curves { get; set; }
+        /// <summary>
+        /// 关联点集合
+        /// </summary>
+        public List<SystemPointItem> Points { get; set; }   
+    }
+}

+ 48 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/Data/SystemPointItem.cs

@@ -0,0 +1,48 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemPointItem
+ * 作者:xulisong
+ * 创建时间: 2019/1/10 11:47:41
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 【系统】点信息描述
+    /// </summary>
+    public class SystemPointItem
+    {
+        /// <summary>
+        /// 几何位置
+        /// </summary>
+        public Point Point { get; set; }
+        /// <summary>
+        /// 关联Id信息
+        /// </summary>
+        public int RefId { get; set; }
+        /// <summary>
+        /// bimId
+        /// </summary>
+        public string BimId { get; set; }
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 设备类型【后续判断方向可能使用】
+        /// </summary>
+        public string EquipmentType { get; set; }
+        /// <summary>
+        ///  是否是虚拟节点【标记立管,特殊阀门,关联空间】
+        /// </summary>
+        public bool IsVirtual { get; set; }
+    }
+}

+ 332 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/FloorSystemItem.cs

@@ -0,0 +1,332 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:FloorSystemItems
+ * 作者:xulisong
+ * 创建时间: 2019/1/4 17:50:04
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using Autodesk.Revit.DB.Plumbing;
+using SAGA.DotNetUtils.Data;
+using SAGA.Models;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public class FloorSystemItem
+    {
+        #region 构造函数
+        /// <summary>
+        /// 初始化解析类
+        /// </summary>
+        /// <param name="doc"></param>
+        public FloorSystemItem(Document doc)
+        {
+            Document = doc;
+            InitData();
+        }
+        #endregion
+        #region 属性相关
+        /// <summary>
+        /// 关联模型信息
+        /// </summary>
+        public Document Document { get; private set; }
+        /// <summary>
+        /// 使用关联标高
+        /// </summary>
+        public Level UseLevel { get; private set; }
+        private bool m_IsInited;
+        /// <summary>
+        /// 初始化数据
+        /// </summary>
+        private void InitData()
+        {
+            if (m_IsInited)
+                return;
+            UseLevel = Document.GetUseView()?.GenLevel;
+            m_IsInited = true;
+        }
+        #endregion
+
+        #region 开始节点获取
+        /// <summary>
+        /// 缓存信息
+        /// </summary>
+        private List<StringFlag<ElementTreeNode>> m_StartNodes;
+        /// <summary>
+        /// 按系统获取开始节点
+        /// </summary>
+        /// <returns></returns>
+        private List<StringFlag<ElementTreeNode>> GetStartNodes()
+        {
+            if (m_StartNodes != null)
+            {
+                //返回没有处理过的节点信息
+                return m_StartNodes.Where(s=>!s.Handled).ToList();
+            }
+            List<StringFlag<ElementTreeNode>> startNodes = new List<StringFlag<ElementTreeNode>>();
+            var doc = Document;
+            #region 立管处理
+            /*
+             * 暂时认定,一个立管之关联一个系统
+             */
+            var verticalPipes = doc.GetElements<Pipe>().Where(p => SystemCalcUtil.IsStart(p) && p.IsVerticalPipe());
+            foreach (var verticalPipe in verticalPipes)
+            {
+                ElementTreeNode node = new ElementTreeNode();
+                node.Current = verticalPipe;
+                var systemTypeName = verticalPipe.GetSystemTypeName();
+                startNodes.Add(new StringFlag<ElementTreeNode>(systemTypeName, node));
+            }
+
+            #endregion
+
+            #region 特殊阀门处理
+
+            ElementCategoryFilter pipeFilter = new ElementCategoryFilter(BuiltInCategory.OST_PipeAccessory);
+            ElementCategoryFilter ductFilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctAccessory);
+            ElementFilter filter = new LogicalOrFilter(pipeFilter, ductFilter);
+            var specialValves = doc.FilterElements(filter).Where(f => SystemCalcUtil.IsStart(f));
+            foreach (var familyInstance in specialValves)
+            {
+                var connector = familyInstance.GetAllConnectors().FirstOrDefault(c => Regex.IsMatch(c.Description, AppSetting.EndFlag));
+                if (connector == null)
+                    continue;
+                var node = SystemParseManager.CreateTreeNode(familyInstance, connector, e => e is MEPCurve);
+                var useMepCurve = node.GetLeaves().FirstOrDefault()?.Current as MEPCurve;
+                if (useMepCurve == null)
+                    continue;
+                var systemTypeName = useMepCurve.GetSystemTypeName();
+                startNodes.Add(new StringFlag<ElementTreeNode>(systemTypeName, node));
+            }
+            #endregion
+
+
+            return m_StartNodes = startNodes;
+        }
+        #endregion
+
+        #region 设备节点获取
+        /// <summary>
+        /// 模型中包含的设备
+        /// </summary>
+        public Dictionary<string, List<FamilyInstance>> RevitEquipments { get; private set; }
+        /// <summary>
+        /// 通过设备类型获取相关设备
+        /// </summary>
+        /// <returns></returns>
+        private List<FamilyInstance> GetEquipments(string category)
+        {
+            if (RevitEquipments == null)
+            {
+                var doc = Document;
+                var fies = doc.FilterElements<FamilyInstance>();
+                List<StringFlag<FamilyInstance>> original = new List<StringFlag<FamilyInstance>>();
+                foreach (var familyInstance in fies)
+                {
+                    var familyName = familyInstance.GetFamily().Name;
+                    if (string.IsNullOrEmpty(familyName))
+                        continue;
+                   var match=Regex.Match(familyName, @"^(?:((?:[A-Z][A-Z]){2,3})\s*-\s*\S*)");
+                    if (match.Success)
+                    {
+                        original.Add(new StringFlag<FamilyInstance>(match.Groups[1].ToString(), familyInstance));
+                    }               
+                }
+                RevitEquipments= original.GroupBy(f => f.Flag).ToDictionary(g=>g.Key,g=>g.ToList().Select(f=>f.Instance).ToList());
+            }
+
+            RevitEquipments.TryGetValue(category, out List<FamilyInstance> result);
+            return result??new List<FamilyInstance>();
+        }
+        #endregion
+
+        #region 数据解析方法
+        /// <summary>
+        /// 解析当前楼层系统数据
+        /// </summary>
+        /// <param name="context"></param>
+        public void Parse(SystemComputerContext context)
+        {
+            var doc = Document;
+            var relations = context.Relations;
+            foreach (var relation in relations)
+            {
+                var shell = context.RelationShells.GetItem(relation);
+                if (shell.IsPipeSystem())
+                {
+                    ParsePipe(context, shell);
+                }
+                else
+                {
+                    ParseDuct(context, shell);
+                }
+            }
+        }
+
+        #region 水系统解析
+        public void ParsePipe(SystemComputerContext context,RelationTypeShell relationSetting)
+        {
+            List<FloorDrawRecord> drawRecords = new List<FloorDrawRecord>();
+            List<FloorRelationRecord> relationRecords = new List<FloorRelationRecord>();
+            #region 计算拓扑树形结构 
+            /*
+             * 1、遍历开始点的限制:特殊阀门,指定标注的Connector;立管,已连接连接件;空间,相交风管元素;
+             * 2、根据拓扑图关联的对象信息,找到系统关联的设备生成节点。如果没有遍历到要独立生成
+             * 3、要不要显示端头管所在空间的位置
+             */
+            var startNodes = GetStartNodes();
+            List<int> useIds = new List<int>();
+            for (int i = 0; i < startNodes.Count; i++)
+            {
+                var startNode = startNodes[i];
+                if (!relationSetting.IsMatchSystem(startNode.Flag))
+                {
+                    continue;
+                }
+                if (useIds.Any(id => id == startNode.Instance.Current.Id.IntegerValue))
+                {
+                    continue;
+                }
+                var tempIds=SystemParseManager.BuildSystemNode(startNode.Instance, Domain.DomainPiping,
+                    (m => !relationSetting.IsMatchSystem(m.GetSystemTypeName())));
+                useIds.AddRange(tempIds);
+                startNode.Handled = true;
+
+                //可以清空Leaves的子节点
+                #region 整理原始数据
+                //判断是否有设备节点,不进行数据处理
+                var useNode = startNode.Instance;
+                var firstEquipment = useNode.FirstOrDefault(t => MBIInfoUtil.IsEquipment(t.Current));
+                //要不要以这个为判定条件,图形可以画出,关系肯定是没有的
+                if (firstEquipment != null)
+                {
+                    //存在设备则保存信息
+                    var drawRecord = BuildFloorDrawRecord(relationSetting, useNode);
+                    drawRecord.SystemName = startNode.Flag;
+                    drawRecords.Add(drawRecord);
+
+                    var relationRecord = BuildFloorRelationRecord(relationSetting, useNode);
+                    relationRecords.Add(relationRecord);
+                }             
+                #endregion
+            }
+            
+            //获取没有使用过的对象节点
+            List<FamilyInstance> singleInstances =
+                relationSetting.RelationItem.Objects.SelectMany(o => GetEquipments(o.Type)).ToList();
+            for (int i = 0; i < singleInstances.Count; i++)
+            {
+                var useInstance = singleInstances[i];
+                if (useIds.Any(id => id == useInstance.Id.IntegerValue))
+                {
+                    continue;
+                }
+                var startNode = new ElementTreeNode() {Current = useInstance};
+                var tempIds = SystemParseManager.BuildSystemNode(startNode, Domain.DomainPiping,
+                    (m => !relationSetting.IsMatchSystem(m.GetSystemTypeName())));
+                useIds.AddRange(tempIds);
+                #region 生成绘图,计算数据
+                //解析数据,找管道定系统,管道找不到,系统名为"关联类型-未知"
+                var firstMepCurve = startNode.FirstOrDefault(t => t.Current is MEPCurve);
+                if (firstMepCurve == null)
+                    continue;
+                var useSystemName = (firstMepCurve.Current as MEPCurve)?.GetSystemTypeName() ?? GetUnknownSystemName(relationSetting);
+                //存在设备则保存信息
+                var drawRecord = BuildFloorDrawRecord(relationSetting, startNode);
+                drawRecord.SystemName = useSystemName;
+                drawRecords.Add(drawRecord);
+
+                var relationRecord = BuildFloorRelationRecord(relationSetting, startNode);
+                relationRecords.Add(relationRecord); 
+                #endregion
+
+            }
+            #endregion
+
+            context.DrawRecords.AddRange(drawRecords);
+            context.RelationRecords.AddRange(relationRecords);
+        }
+        #endregion
+
+        #region 风系统解析
+        public void ParseDuct(SystemComputerContext context, RelationTypeShell relationSetting)
+        { } 
+        #endregion
+        #endregion
+
+        #region 解析立管
+        /*
+         * 1、解析立管需要考虑,竖直风管,水管,空间的情况;
+         *2、将各层数据汇总,才能统一计算立管的相关关系数据
+         */
+        private void ComputerVerticalPipes(Level refLevel, List<Pipe> pipes, SystemComputerContext context)
+        {
+            var result = new List<VerticalPipe>();
+            var spaces = Document.GetElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).OfType<Space>();
+            var level = refLevel;
+            var currentLevelName = MBIInfoUtil.GetFloorNameByLevel(level.Name);
+            foreach (var pipe in pipes)
+            {
+                if (pipe == null)
+                    continue;             
+                var vp = new VerticalPipe
+                {
+                    Id = pipe.Id.IntegerValue.ToString(),
+                    LevelName = currentLevelName,
+                    LevelElevation = level.Elevation,
+                    UpPoint3D = PointConverter.XYZToPoint3D(pipe.GetVerticalTopPoint()),
+                    DownPoint3D = PointConverter.XYZToPoint3D(pipe.GetVerticalBottomPoint()),
+                    PipeSytemType = pipe.GetSystemTypeName()
+                };
+                #region  获取立管关联空间
+                var locationCurve = pipe.GetLocationCurve();
+                var midPoint = (locationCurve.StartPoint() + locationCurve.EndPoint()) / 2;
+                Space refSpace = spaces.FirstOrDefault(s => s.IsPointInSpace(midPoint));//关联
+                var display = context.GetSpaceDisplay(refSpace, out string tip);
+                vp.Display = $"{display}:{pipe.Id.IntegerValue.ToString()}";
+                vp.DisplayTip = tip ?? string.Empty; 
+                #endregion
+                result.Add(vp);
+            }
+            LevelData levelData = new LevelData()
+            {
+                Id = refLevel.Id.ToString(),
+                Name = MBIInfoUtil.GetFloorNameByLevel(refLevel.Name)
+            };
+            context.VerticalPipes.AddRange(result);
+            context.Levels.Add(levelData);
+        }
+        #endregion
+
+
+        #region 保存数据类对象创建
+
+        private string GetUnknownSystemName(RelationTypeShell relationShell)
+        {
+            return relationShell.RelationItem?.Name + "---未知";
+        }
+        private FloorDrawRecord BuildFloorDrawRecord(RelationTypeShell relationShell,ElementTreeNode node)
+        {
+            var floorDraw = new FloorDrawRecord();
+            floorDraw.SetFloorLevel(UseLevel);
+            floorDraw.RelationType = relationShell.RelationItem.Type;
+            floorDraw.DrawIems = SystemParseManager.CreateDrawing(node)??new SystemDrawItems();
+            return floorDraw;
+        }
+        private FloorRelationRecord BuildFloorRelationRecord(RelationTypeShell relationShell, ElementTreeNode node)
+        {
+            var floorRelation = new FloorRelationRecord();
+            floorRelation.SetFloorLevel(UseLevel);
+            floorRelation.RelationType = relationShell.RelationItem.Type;
+            floorRelation.EquipmentItems = SystemParseManager.CreateRelation(node)??new List<EquipmentNode>();
+            return floorRelation;
+        }
+        #endregion
+    }
+}

+ 0 - 48
MBI/SAGA.GplotRelationComputerManage/SystemRelation/FloorSystemItems.cs

@@ -1,48 +0,0 @@
-/*-------------------------------------------------------------------------
- * 功能描述:FloorSystemItems
- * 作者:xulisong
- * 创建时间: 2019/1/4 17:50:04
- * 版本号:v1.0
- *  -------------------------------------------------------------------------*/
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Autodesk.Revit.DB;
-
-namespace SAGA.GplotRelationComputerManage
-{
-    public class FloorSystemItems
-    {
-        #region 构造函数
-        /// <summary>
-        /// 初始化解析类
-        /// </summary>
-        /// <param name="doc"></param>
-        public FloorSystemItems(Document doc)
-        {
-            Document = doc;
-            InitData();
-        }
-        #endregion
-        #region 属性相关
-        /// <summary>
-        /// 关联模型信息
-        /// </summary>
-        public Document Document { get; private set; }
-        private void InitData()
-        { }
-        #endregion
-
-        #region 数据解析方法
-        public void ParsePipe()
-        { }
-
-        public void ParseDuct()
-        { }
-        #endregion
-
-    }
-}

+ 27 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorDrawRecord.cs

@@ -0,0 +1,27 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:FloorDrawRecord
+ * 作者:xulisong
+ * 创建时间: 2019/1/17 17:41:56
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    public class FloorDrawRecord : FloorFlag
+    {
+        /// <summary>
+        /// 系统名称信息
+        /// </summary>
+        public string SystemName { get; set; }
+        /// <summary>
+        /// 绘图数据
+        /// </summary>
+        public SystemDrawItems DrawIems { get; set; }
+    }
+}

+ 49 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorRecord.cs

@@ -0,0 +1,49 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:FloorFlag
+ * 作者:xulisong
+ * 创建时间: 2019/1/17 17:39:38
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.DB;
+using SAGA.RevitUtils.Extends;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{ 
+    /*
+     * 整体上不采用树形结构存储
+     */
+    /// <summary>
+    /// 楼层信息记录
+    /// </summary>
+    public class FloorFlag
+    {
+        public string FloorName { get; set; }
+        public string FloorIndex { get; set; }
+        /// <summary>
+        /// 楼层高度
+        /// </summary>
+        public double FloorLevelElevation { get; set; }
+        /// <summary>
+        /// 关联类型
+        /// </summary>
+        public string RelationType { get; set; }
+
+        /// <summary>
+        /// 设置楼层信息
+        /// </summary>
+        /// <param name="level"></param>
+        public void SetFloorLevel(Level level)
+        {
+            if (level == null)
+                return;
+            FloorName = MBIInfoUtil.GetFloorNameByLevel(level.Name);
+            FloorLevelElevation = level.ProjectElevation.FromApi();
+        }
+    }
+}

+ 23 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/ServerData/FloorRelationRecord.cs

@@ -0,0 +1,23 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:FloorRelationRecord
+ * 作者:xulisong
+ * 创建时间: 2019/1/17 17:42:36
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SAGA.GplotRelationComputerManage
+{
+   public  class FloorRelationRecord: FloorFlag
+    {
+        /// <summary>
+        /// 关联数据
+        /// </summary>
+        public List<EquipmentNode> EquipmentItems { get; set; }
+    }
+}

+ 67 - 22
MBI/SAGA.GplotRelationComputerManage/SystemRelation/SystemComputerContext.cs

@@ -7,49 +7,94 @@
 
 using System;
 using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using SAGA.RevitUtils.Extends;
-
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.DotNetUtils.Cache;
+using SAGA.Models;
+using SAGA.RevitUtils;
+using MBIEquipItem = SAGA.Models.EquipmentItem;
 namespace SAGA.GplotRelationComputerManage
 {
     public class SystemComputerContext
     {
         public SystemComputerContext()
         {
-            FloorItems = new Dictionary<string, FloorSystemItems>();
+            #region 初始化
+            FloorItems = SystemCalcUtil.CreateFloorItems();
+            Rooms = SystemCalcUtil.CreateRoomItems();
+            RelationShells = SystemCalcUtil.CreateRelationShellItems();
+            EquipmentItems = SystemCalcUtil.CreateEquipmentItems();
+            VerticalPipes = new List<VerticalPipe>();
+            Levels = new List<LevelData>();
+            Relations = new List<string>();
+            DrawRecords = new List<FloorDrawRecord>();
+            RelationRecords = new List<FloorRelationRecord>();
+            #endregion
         }
-        #region 空间计算缓存信息
+        #region 计算缓存对象
+        /// <summary>
+        /// 缓存空间对象
+        /// </summary>
+        public CacheItems<string, RoomItem> Rooms { get; private set; }
         /// <summary>
         /// 楼层系统数据缓存
         /// </summary>
-        public Dictionary<string, FloorSystemItems> FloorItems { get; private set; }
+        public CacheItems<string, FloorSystemItem> FloorItems { get; private set; }
+
+        public CacheItems<string, MBIEquipItem> EquipmentItems { get; private set; }
 
+        #endregion
+
+        #region 一些上下文相关的方法
+        private const string UnKnowSpace = "未知空间:BIMID编码";
+        private const string SiSpace = "空间本地名称:BIMID编码";
+        private const string ModelSpace = "空间模型名称:BIMID编码";
         /// <summary>
-        /// 获取指定路径项目的楼层信息
+        /// 获取空间描述信息,立管使用
         /// </summary>
-        /// <param name="path"></param>
+        /// <param name="space"></param>
+        /// <param name="tip"></param>
         /// <returns></returns>
-        public FloorSystemItems GetFloorItems(string path)
+        public string GetSpaceDisplay(Space space, out string tip)
         {
-            var floorId = Path.GetFileNameWithoutExtension(path);
-            if (FloorItems.TryGetValue(floorId, out FloorSystemItems floor))
+            tip = string.Empty;
+            if (space == null)
             {
-                return floor;
+                tip = UnKnowSpace;
+                return "未知";
             }
-
-            if (File.Exists(path))
+            string bimId = space.GetBimId();
+            var room = Rooms.GetItem(bimId);
+            string useName = space.Name;
+            tip = ModelSpace;
+            if (room != null && !string.IsNullOrWhiteSpace(room.LocalName))
             {
-                var uiApp = ExternalDataWrapper.Current.UiApp.Application;
-                var doc = uiApp.OpenDocumentFile(path);
-                floor = new FloorSystemItems(doc);
-                FloorItems[floorId] = floor;
+                tip = SiSpace;
+                useName = room.LocalName;
             }
-            return floor;
+            return useName;
         }
+        #endregion
+
+        #region 计算结果存储类
+        /*
+         *计算数据存储在Context中,FloorSystemItem尽量只跟解析算法相关
+         */
+        public List<VerticalPipe> VerticalPipes { get; private set; }
+        public List<LevelData> Levels { get; private set; }
+        public List<FloorDrawRecord> DrawRecords { get; private set; }
+        public List<FloorRelationRecord> RelationRecords { get; private set; }
+        #endregion
 
+        #region 需要计算的系统相关
+        /// <summary>
+        /// 缓存关系计算壳对象
+        /// </summary>
+        public CacheItems<string, RelationTypeShell> RelationShells { get; private set; }
+        
+        /// <summary>
+        /// 需要计算的关系类型
+        /// </summary>
+        public List<string> Relations { get;private set; }
         #endregion
     }
 }

+ 37 - 0
MBI/SAGA.GplotRelationComputerManage/SystemRelation/SystemComputerHandler.cs

@@ -0,0 +1,37 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:SystemComputerHandler
+ * 作者:xulisong
+ * 创建时间: 2019/1/17 9:42:03
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SAGA.MBI.Tools;
+
+namespace SAGA.GplotRelationComputerManage
+{
+   public  class SystemComputerHandler
+    {
+        public List<object> GetParseData(SystemComputerContext context)
+        {
+            List<object> items = new List<object>();
+            var fileInfos = RevitModelPath.GetAllRevitFiles();
+            foreach (var fileInfo in fileInfos)
+            {
+                if (File.Exists(fileInfo))
+                {
+                    FloorSystemItem floorItems = context.FloorItems.GetItem(fileInfo);
+                    floorItems.Parse(context);
+                    floorItems.Document.CloseDocSimple();
+                }
+            }
+            //最后统保存缓存数据
+            return items;
+        }
+    }
+}

+ 31 - 13
MBI/SAGA.MBI/Interaction/MBIModelInfoManager.cs

@@ -1,17 +1,14 @@
-
-using Autodesk.Revit.DB;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.Mechanical;
 using SAGA.DotNetUtils.Extend;
 using SAGA.MBI.Calc;
 using SAGA.Models;
 using SAGA.RevitUtils.Extends;
 using SAGA.MBI.DataArrange;
-using SAGA.MBI.RevitExport;
+using SAGA.MBI.RevitModelHandle;
 
 namespace SAGA.MBI.Interaction
 {
@@ -20,6 +17,28 @@ namespace SAGA.MBI.Interaction
     /// </summary>
     public class MBIModelInfoManager
     {
+       /// <summary>
+       /// 通过mbi元素对模型进行更新
+       /// </summary>
+       /// <param name="element"></param>
+       /// <param name="mbiItem"></param>
+        private static void UpdateElement(Element element, MBIItem mbiItem)
+        {
+            do
+            {
+                if (element is Space)
+                {
+                    RevitParameterUpdate.UpdateElementByMbi(element,MBIBuiltInParameter.RoomLocalName, mbiItem.LocalName);
+                    break;
+                }
+                if (element is FamilyInstance)
+                {
+                    RevitParameterUpdate.UpdateElementByMbi(element, MBIBuiltInParameter.EquipLocalName, mbiItem.LocalName);
+                    RevitParameterUpdate.UpdateElementByMbi(element, MBIBuiltInParameter.EquipLocalID, mbiItem.LocalId);                 
+                    break;
+                }
+            } while (false);
+        }
         /// <summary>
         /// 同步物理世界信息到revit
         /// </summary>
@@ -41,17 +60,13 @@ namespace SAGA.MBI.Interaction
                     tran.Start();
                     foreach (var mbiItem in mbiItems)
                     {
-                        if (string.IsNullOrEmpty(mbiItem.LocalName))
-                        {
-                            //本地名称为null,则不信息修改;
-                            continue;
-                        }
                         #region 核心处理模型修改
                         using (SubTransaction sub = new SubTransaction(document))
                         {
                             try
                             {
                                 sub.Start();
+                                #region 获取revit对象
                                 var id = mbiItem.RevitId;
                                 if (id <= 0)
                                     continue;
@@ -59,8 +74,11 @@ namespace SAGA.MBI.Interaction
                                 if (element == null)
                                 {
                                     continue;
-                                }
-                                 element.UdpateName(mbiItem.LocalName,true);                           
+                                } 
+                                #endregion
+
+                                UpdateElement(element, mbiItem);
+                                 //element.UdpateName(mbiItem.LocalName,true);                           
                                 sub.Commit();
                             }
                             catch (Exception e)

+ 1 - 1
MBI/SAGA.MBI/Model/MRevitEquipBase.cs

@@ -271,7 +271,7 @@ namespace SAGA.MBI.Model
                     {
                         if (info.PropertyType == typeof(int))
                             value = ((int)value).ToString();
-                        RevitParameterUpdate.UpdateParameter(BimID, description, value.ToString());
+                        RevitParameterUpdate.UpdateRevitParameter(BimID, description, value.ToString());
                         UpdateSingleProperty(description, (string)value);
                     }
                 }

+ 54 - 0
MBI/SAGA.MBI/RevitModelHandle/ParameterDefinitionFactory.cs

@@ -0,0 +1,54 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:MBIParameterMapUtil
+ * 作者:xulisong
+ * 创建时间: 2019/1/22 11:09:57
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using SAGA.Models;
+
+namespace SAGA.MBI.RevitModelHandle
+{
+    public class ParameterDefinitionFactory
+    {
+        private static Dictionary<string, ParameterDefinition> m_InnerMap=new Dictionary<string, ParameterDefinition>();
+
+        static ParameterDefinitionFactory()
+        {
+            m_InnerMap[MBIBuiltInParameter.EquipLocalID] = new ParameterDefinition("设备本地编号");
+            m_InnerMap[MBIBuiltInParameter.EquipLocalName] = new ParameterDefinition("设备本地名称");
+            m_InnerMap[MBIBuiltInParameter.RoomLocalName] = new ParameterDefinition(BuiltInParameter.ROOM_NAME){CanUpdate=
+                (e, value) =>
+                {
+                    if (e is Space space)
+                    {
+                        return space.Name != value;
+                    }
+                    return true;
+                }
+            };
+        }
+
+        public static bool ContainParameter(string mbiParameterName)
+        {
+            return m_InnerMap.ContainsKey(mbiParameterName);
+        }
+        /// <summary>
+        /// 根据mbi参数获取参数定义
+        /// </summary>
+        /// <param name="mbiParameterName"></param>
+        /// <returns></returns>
+        public static ParameterDefinition GetParameterDefinition(string mbiParameterName)
+        {
+            m_InnerMap.TryGetValue(mbiParameterName, out ParameterDefinition definiton);
+            return definiton;
+        }
+    }
+}

+ 183 - 0
MBI/SAGA.MBI/RevitModelHandle/ParameterUtil.cs

@@ -0,0 +1,183 @@
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils;
+
+namespace SAGA.MBI.RevitModelHandle
+{
+    /// <summary>
+    /// 参数定义
+    /// </summary>
+    public class ParameterDefinition
+    {
+        #region 封装输入参数
+        /*
+         * 将多种参数查询统一形式
+         */ 
+        #endregion
+        public ParameterDefinition(string parameterName)
+        {
+            BuiltInParameter = BuiltInParameter.INVALID;
+            Name = parameterName;
+        }
+        public ParameterDefinition(BuiltInParameter builtInParameter)
+        {
+            BuiltInParameter = builtInParameter;
+        }
+        /// <summary>
+        /// 参数名称
+        /// </summary>
+        public string Name { get;private set; }
+        /// <summary>
+        /// 参数类别
+        /// </summary>
+        public BuiltInParameter BuiltInParameter
+        {
+            get;private set;
+        }
+
+        /// <summary>
+        /// 修改检测[ture是]
+        /// </summary>
+        public Func<Element,string,bool> CanUpdate{ get; set; }
+        /// <summary>
+        /// 获取指定元素的参数
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public Parameter LookupParameter(Element element)
+        {
+            if (BuiltInParameter.INVALID != BuiltInParameter)
+            {
+                return element.get_Parameter(BuiltInParameter);
+            }
+            else
+            {
+                return element.LookupParameter(Name);
+            }
+        }
+
+        /// <summary>
+        /// 这顶指定元素的值
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="value"></param>
+        public void SetParameter(Element element, string value)
+        {
+            var parameter = LookupParameter(element);
+            if (parameter == null)
+                return;
+            var oldValue = ParameterUtil.GetParameterValue(parameter);
+            if (oldValue == value)
+                return;
+            if (CanUpdate != null && !CanUpdate(element, value))
+                return;
+            ParameterUtil.SetParameterValue(parameter,value);
+        }
+    }
+    public class ParameterUtil
+    {
+        #region 描述
+        /*
+         * 传入的value值统一成string类型,再去转化;
+         * 类似于传统控件的前台输入,输入信息都是value;
+         * 需要调整在调
+         */
+        #endregion
+        /// <summary>
+        /// 设置参数
+        /// </summary>
+        /// <param name="parameter"></param>
+        /// <param name="value"></param>
+        public static void SetParameterValue(Parameter parameter, string value)
+        {
+            if (parameter == null || parameter.IsReadOnly)
+                return;
+            switch (parameter.StorageType)
+            {
+                case StorageType.Double:
+                    {
+                        parameter.Set(value.ToDouble());
+                        break;
+                    }
+                case StorageType.String:
+                    {
+                        parameter.Set(value);
+                        break;
+                    }
+                case StorageType.Integer:
+                    {
+                        parameter.Set(value.ToInt());
+                        break;
+                    }
+                case StorageType.ElementId:
+                    {
+                        parameter.Set(new ElementId(value.ToInt()));
+                        break;
+                    }
+            }
+        }
+        /// <summary>
+        /// 获取参数
+        /// </summary>
+        /// <param name="parameter"></param>
+        /// <returns></returns>
+        public static string GetParameterValue(Parameter parameter)
+        {
+            string result = string.Empty;
+            if (parameter == null || parameter.IsReadOnly)
+                return null;
+            switch (parameter.StorageType)
+            {
+                case StorageType.Double:
+                    {
+                        result = parameter.AsDouble().ToString();
+                        break;
+                    }
+                case StorageType.String:
+                    {
+                        result = parameter.AsString()?.ToString();
+                        break;
+                    }
+                case StorageType.Integer:
+                    {
+                        result = parameter.AsInteger().ToString();
+                        break;
+                    }
+                case StorageType.ElementId:
+                    {
+                        result = parameter.AsElementId()?.ToString();
+                        break;
+                    }
+            }
+            return result;
+        }
+        /// <summary>
+        /// 设置参数
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="definition"></param>
+        /// <param name="value"></param>
+        public static void SetParameterValue(Element element, ParameterDefinition definition, string value)
+        {
+            var parameter = definition.LookupParameter(element);
+            SetParameterValue(parameter, value);
+        }
+        /// <summary>
+        /// 获取参数
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="definition"></param>
+        /// <returns></returns>
+        public static string GetParameterValue(Element element, ParameterDefinition definition)
+        {
+            var parameter = definition.LookupParameter(element);
+            return GetParameterValue(parameter);         
+        }
+    }
+}

+ 99 - 86
MBI/SAGA.MBI/RevitModelHandle/RevitParameterUpdate.cs

@@ -1,10 +1,8 @@
-using Autodesk.Revit.DB;
+
 using System;
-using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.Mechanical;
 using Newtonsoft.Json.Linq;
 using SAGA.DotNetUtils;
@@ -12,8 +10,8 @@ using SAGA.MBI.Common;
 using SAGA.MBI.DataArrange;
 using SAGA.MBI.Interaction;
 using SAGA.MBI.RequestData;
+using SAGA.MBI.RevitModelHandle;
 using SAGA.Models;
-using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
 using SAGA.RevitUtils.Windows;
 
@@ -24,64 +22,87 @@ namespace SAGA.MBI
     /// </summary>
     public static class RevitParameterUpdate
     {
-        #region 同步模型
-        /// <summary>
-        /// 更新模型名称
-        /// </summary>
-        /// <param name="element"></param>
-        /// <param name="name"></param>
-        public static void UdpateName(this Element element, string name)
-        {
-            string useName = name ?? string.Empty;
-            do
-            {
-                if (element is Space space)
-                {
-                    if (space.Name != useName && space.GetParameterString(BuiltInParameter.ROOM_NAME) != useName)
-                    {
-                        space.SetParameter(BuiltInParameter.ROOM_NAME, useName);
-
-                    }
-                }
-            } while (false);
-        }
+        #region 基础方法
         /// <summary>
-        /// 更新元素名称
+        /// 根据bimId获取模型对象
         /// </summary>
-        /// <param name="element"></param>
-        /// <param name="name"></param>
-        /// <param name="stopLocalTrigger">是否暂停触发器,暂停触发器则不会发送对数据平台的同步</param>
-        public static void UdpateName(this Element element, string name, bool stopLocalTrigger)
+        /// <param name="bimId"></param>
+        /// <returns></returns>
+        public static Element GetElementByBimId(string bimId)
         {
-            if (!stopLocalTrigger)
-            {
-                UdpateName(element, name);
-                return;
-            }
-            try
-            {
-                MBILocalNameTrigger.Suspend();
-                UdpateName(element, name);
-            }
-            catch (Exception ex)
+            Element result = null;
+            #region 获取revit对象
+            if (bimId == null)
+                return result;
+            var ids = bimId.Split(':');
+            if (ids.Count() < 2)
+                return result;
+            string floorId = ids[0];
+            int elementID = ids[1].ToInt();
+            var mFloor = DalProjectTree.GetFloorByFloorId(floorId);
+            if (mFloor == null)
             {
+                return result;
             }
-            finally
+            if (!File.Exists(mFloor.FullPath))
             {
-                MBILocalNameTrigger.Resume();
+                return result;
             }
-        }
+            var doc = ExternalDataWrapper.Current.App.OpenDocumentFile(mFloor.FullPath);
+            if (doc == null)
+                return result;
+            result = doc.GetElement(new ElementId(elementID));
+            #endregion
 
-        public static void UpdateNameAsync(this Element element, string name)
+            return result;
+        }
+        #endregion
+        #region 同步模型
+        #region 触发器控制,方法取消
+        ///// <summary>
+        ///// 更新模型空间名称
+        ///// </summary>
+        ///// <param name="element"></param>
+        ///// <param name="name"></param>
+        ///// <param name="stopLocalTrigger">是否暂停触发器,暂停触发器则不会发送对数据平台的同步</param>
+        //public static void UdpateName(this Element element, string name, bool stopLocalTrigger)
+        //{
+        //    if (!stopLocalTrigger)
+        //    {
+        //        //UdpateName(element, name);
+        //        return;
+        //    }
+        //    try
+        //    {
+        //        MBILocalNameTrigger.Suspend();
+        //        //UdpateName(element, name);
+        //    }
+        //    catch (Exception ex)
+        //    {
+        //    }
+        //    finally
+        //    {
+        //        MBILocalNameTrigger.Resume();
+        //    }
+        //} 
+        #endregion
+        public static void UpdateRevitParameter(string bimId, string parameterName,string value)
         {
+            if (!ParameterDefinitionFactory.ContainParameter(parameterName))
+                return;
+            var element = GetElementByBimId(bimId);
+            if (element == null)
+                return;
+          
             ExecuteCmd.ExecuteCommand(() =>
             {
-                using (Transaction tran = new Transaction(element.Document, "同步"))
+                using (Transaction tran = new Transaction(element.Document, "更改"))
                 {
                     try
                     {
                         tran.Start();
-                        UdpateName(element, name, true);
+                        //不检测值是否为null 
+                        UpdateElementByMbi(element, parameterName, value, false);
                         tran.Commit();
                     }
                     catch (Exception e)
@@ -91,48 +112,20 @@ namespace SAGA.MBI
                 }
                 return Autodesk.Revit.UI.Result.Succeeded;
             });
-        }
-        public static void UpdateNameAsync(string bimId, string name)
-        {
-            if (bimId == null)
-                return;
-            var ids = bimId.Split(':');
-            if (ids.Count() < 2)
-                return;
-            string floorId = ids[0];
-            int elementID = ids[1].ToInt();
-            var mFloor = DalProjectTree.GetFloorByFloorId(floorId);
-            if (mFloor == null)
-            {
-                return;
-            }            
-            if (!File.Exists(mFloor.FullPath))
-            {
-                return;
-            }
-            var doc = ExternalDataWrapper.Current.App.OpenDocumentFile(mFloor.FullPath);// ExternalDataWrapper.Current.Doc;
-            if (doc == null)
-                return;
-            var element = doc.GetElement(new ElementId(elementID));
-            if (element == null)
-                return;
-            UpdateNameAsync(element, name);
-        }
-
-
-        public static void UpdateParameter(string bimId, string parameterName,string value)
-        {
-            if (parameterName == MBIBuiltInParameter.RoomLocalName)
-            {
-                UpdateNameAsync(bimId, value);
-            }         
+        
         }
 
         #endregion
+        #region 更新物理世界相关信息
+        /// <summary>
+        /// 更新空间的名称信息
+        /// </summary>
+        /// <remarks>触发器使用,现在被砍掉了</remarks>
+        /// <param name="element"></param>
+        /// <param name="name"></param>
         public static void UpdateMBIName(this Element element, string name)
         {
-            //更新物理世界信息点内容
-            var bimId = element.GetBimId();         
+            //更新物理世界信息点内容     
             JArray jArray = CommonTool.GetPropertyJArray(name);
             JObject jObject = new JObject();
             jObject.Add(MBIBuiltInParameter.RoomLocalName, jArray);
@@ -140,7 +133,27 @@ namespace SAGA.MBI
             if (cloudElement == null)
                 return;
             CommonConvert.UpdateInfosSigle(cloudElement.Id, jObject);
-           // MessageShow.Infomation(bimId);
         }
+        #endregion
+
+        #region 通过mbi更新,模型信息
+        /// <summary>
+        /// 更新元素信息值
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="mbiParameterName"></param>
+        /// <param name="value"></param>
+        public static void UpdateElementByMbi(Element element, string mbiParameterName, string value)
+        {
+            UpdateElementByMbi(element, mbiParameterName, value, true);
+        }
+        public static void UpdateElementByMbi(Element element, string mbiParameterName, string value, bool checkValueEmpty)
+        {
+            if (checkValueEmpty && string.IsNullOrWhiteSpace(value))
+                return;
+            ParameterDefinitionFactory.GetParameterDefinition(mbiParameterName)
+                ?.SetParameter(element, value);
+        } 
+        #endregion
     }
 }

+ 2 - 0
MBI/SAGA.MBI/SAGA.MBI.csproj

@@ -279,6 +279,8 @@
     <Compile Include="Model\MBSpace.cs" />
     <Compile Include="Model\MQRCode.cs" />
     <Compile Include="RequestData\QRCodeRequest.cs" />
+    <Compile Include="RevitModelHandle\ParameterDefinitionFactory.cs" />
+    <Compile Include="RevitModelHandle\ParameterUtil.cs" />
     <Compile Include="RevitModelHandle\RevitParameterUpdate.cs" />
     <Compile Include="RevitReference\RVTNoModeDutyOperate.cs" />
     <Compile Include="Service\InputService.cs" />

+ 47 - 0
MBI/SAGA.Models/ChangesRelationship.cs

@@ -38,5 +38,52 @@ namespace SAGA.Models
         public string PipeSystemType { get; set; }
         [CellIndex(9)]
         public string FlowFlag { get; set; }
+
+        /// <summary>
+        /// 边方向
+        /// </summary>
+        [CellIndex(5)]
+        public string EdgeDirection { get; set; }
+        /// <summary>
+        /// 对象信息
+        /// </summary>
+        [CellIndex(6)]
+        public string Objects { get; set; }
+        /// <summary>
+        /// 系统信息
+        /// </summary>
+        [CellIndex(11)]
+        public string Systems { get; set; }
+    }
+
+    /// <summary>
+    /// 关系行
+    /// </summary>
+    [SheetInfo(SheetName = "Sheet1", RowStartIndex = 2)]
+    public class RelationRow
+    {
+        [CellIndex(1)]
+        public string RelationshipType { get; set; }
+        [CellIndex(2)]
+        public string RelationName { get; set; }
+        [CellIndex(3)]
+        public string EdgeType { get; set; }
+        [CellIndex(4)]
+        public string EdgeName { get; set; }
+        /// <summary>
+        /// 边方向
+        /// </summary>
+        [CellIndex(5)]
+        public string EdgeDirection { get; set; }
+        /// <summary>
+        /// 对象信息
+        /// </summary>
+        [CellIndex(6)]
+        public string Objects { get; set; }
+        /// <summary>
+        /// 系统信息
+        /// </summary>
+        [CellIndex(10)]
+        public string Systems { get; set; }
     }
 }

+ 2 - 75
MBI/SAGA.Models/StaticData.cs

@@ -10,33 +10,9 @@ using SAGA.DotNetUtils.Utilities;
 
 namespace SAGA.Models {
     public static class StaticData {
-        public static readonly string MBIResourcePath = Path.Combine(AppBaseInfo.AppRunPath, @"MBIResource");
-      
+        public static readonly string MBIResourcePath = Path.Combine(AppBaseInfo.AppRunPath, @"MBIResource");   
         public static readonly string ChangesRelationship = Path.Combine(MBIResourcePath, @"Config\物理世界关系定义列表.xlsx");
-        public static readonly string GdRelationship = Path.Combine(MBIResourcePath, @"Config\物理世界关系定义列表-20180928.xlsx");
-        public static string BaseUrl => GetData("url");
-
-        public static string ProjId => ProjectInfo.ProId;
-
-        public static string ProjPassword => ProjectInfo.Password;
-
-
-        public static string GetData(string key) {
-            return IniOperator.GetSetting(key);
-        }
-        public static void SaveData(string key, string value) {
-
-            IniOperator.SetSetting(key, value);
-
-        }
-        public static string GetProInfoData(string key) {
-            return IniOperator.GetData("ProInfo", key);
-        }
-
-        public static void SaveProInfoData(string key, string value) {
-            IniOperator.SetData("ProInfo", key, value);
-        }
-
+        public static readonly string GdRelationship = Path.Combine(MBIResourcePath, @"Config\物理世界关系定义列表-2019-1.xlsx");        
         /// <summary>
         /// 所有项目的根目录
         /// </summary>
@@ -45,11 +21,8 @@ namespace SAGA.Models {
             get
             {
                 string projectId = IniOperator.GetData("CurProject", "ID");
-               // string workPath = IniOperator.GetData("ProjectDir", projectId);
-
                 return Path.Combine(Path.GetTempPath(),"Revit", projectId);
             }
-            set => SaveData(nameof(ProjectsRoot), value);
         }
 
         /// <summary>
@@ -57,18 +30,6 @@ namespace SAGA.Models {
         /// </summary>
         public static string ProjectDirectory => ProjectsRoot;
         /// <summary>
-        /// 当前项目Revit文件所在目录
-        /// </summary>
-        public static string RevitDirectory => Path.Combine(ProjectDirectory, ProjectInfo.Name);
-
-        /// <summary>
-        /// 项目信息
-        /// </summary>
-
-        public static ProjectInfo ProjectInfo => GetData<ProjectInfo>();
-
-
-        /// <summary>
         /// 当前项目数据文件所在目录
         /// </summary>
         public static string DbDirectory
@@ -83,39 +44,5 @@ namespace SAGA.Models {
                 return path;
             }
         }
-        public static void SaveData<T>(T t) {
-            IniOperator.SaveData(t);
-        }
-        public static T GetData<T>() where T : class, new() {
-            return IniOperator.GetData<T>();
-        }
-
-        /// <summary>
-        /// 文件路径设置
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private static string GetRoot() {
-            FolderBrowserDialog fbd = new FolderBrowserDialog();
-            fbd.ShowNewFolderButton = true;
-            fbd.Description = "请选择文件存储根目录";
-            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) return null;
-
-
-            return fbd.SelectedPath.Trim();
-        }
-    }
-    public class Config {
-        public static string AccessKeyId = "LTAIHLlfCwmMRbV4";
-
-        public static string AccessKeySecret = "TixG1tTpeNnM96FPVC33fumK8QAUsv";
-
-        public static string Endpoint = "oss-cn-beijing.aliyuncs.com";
-
-        public static string DirToDownload = @"E:\上帝之手项目文件\";
-
-        public static string FileToUpload = @"E:\上帝之手项目文件\Pj1101080002.zip";
-
-        public static string BigFileToUpload = @"E:\上帝之手项目文件\Pj1101080002.zip";
     }
 }

+ 3 - 3
MBI/SAGA.RevitUtils/MEP/MepJoinUtil.cs

@@ -82,10 +82,10 @@ namespace SAGA.RevitUtils.MEP
         /// <param name="startElement"></param>
         /// <param name="connectorSpecify"></param>
         /// <returns></returns>
-        public static List<Element> GetFirstElements<T>(this Element startElement,
+        public static List<T> GetFirstElements<T>(this Element startElement,
             Connector connectorSpecify = null) where T : Element
         {
-            List<Element> sameTypeElements = new List<Element>();
+            List<T> sameTypeElements = new List<T>();
             List<Element> reference = new List<Element>();
             reference.Add(startElement);
             for (int i = 0; i < reference.Count; i++)
@@ -119,7 +119,7 @@ namespace SAGA.RevitUtils.MEP
                             {
                                 if (sameTypeElements.All(e => e.Id.IntegerValue != element.Id.IntegerValue))
                                 {
-                                    sameTypeElements.Add(element);
+                                    sameTypeElements.Add(temp);
                                 }
                             }
                         }

+ 33 - 0
MBI/SAGA.RevitUtils/MEP/TNode.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace SAGA.RevitUtils.MEP
 {
@@ -266,6 +267,38 @@ namespace SAGA.RevitUtils.MEP
         public T Parent { get; set; }
 
         public object Tag { get; set; }
+
+        #region 便捷查找
+
+        public T FirstOrDefault()
+        {
+            return this as T;
+        }
+        /// <summary>
+        /// 查找第一个满足条件的节点
+        /// </summary>
+        /// <param name="predicateNode"></param>
+        /// <returns></returns>
+        public T FirstOrDefault(Predicate<T> predicateNode)
+        {
+            if (predicateNode == null)
+                return this as T;
+            var usePredicate = predicateNode;
+            var queueNodes = new Queue<T>();
+            queueNodes.Enqueue(this as T);
+            while (queueNodes.Any())
+            {
+                var useNode = queueNodes.Dequeue();
+                if (usePredicate(useNode))
+                {
+                    return useNode;
+                }
+
+                useNode.Nodes.ToList().ForEach(queueNodes.Enqueue);
+            }
+            return null;
+        }
+        #endregion
     }
 }