Browse Source

xls:空间计算效率和准确度改善

xulisong 6 years ago
parent
commit
be9317be24

BIN
MBI/Dlls/FirmLibDll/FWindSoft.Wpf.dll


BIN
MBI/Dlls/FirmLibDll/FWindSoft.Wpf.pdb


BIN
MBI/Dlls/FirmLibDll/FWindSoft.dll


BIN
MBI/Dlls/FirmLibDll/FWindSoft.pdb


+ 0 - 1
MBI/SAGA.GplotDrawData/DBView/SpaceGraphView.cs

@@ -7,7 +7,6 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Media;
-using Node=SAGA.Models.Graphs.GNode;
 
 namespace SAGA.GplotDrawData
 {

+ 0 - 172
MBI/SAGA.GplotDrawData/DBView/VirticalSpaceGraphView.cs

@@ -87,178 +87,6 @@ namespace SAGA.GplotDrawData
         {
             return this.SpaceType == spaceType;
         }
-       
-        public  GraphDB AppendDb1(SpaceData td, GraphDB db)
-        {
-            var levels = td.LevelNames;
-
-            //按标高排序,按名称分组
-            double width = 1000;
-            var hoffset = 100;
-            var voffset = 100;
-            var hseq = 200;
-            var vseq = 100;
-            var start = new Point(hoffset, voffset);
-            var index = 1;
-            for (int i = 0; i < levels.Count; i++)
-            {
-                #region 画标高
-                var startTemp = new Point(start.X, start.Y + i * vseq);
-                var endTemp = new Point(start.X + width - 2 * hoffset - 100, start.Y + i * vseq);
-                var line2 = new GLine(startTemp.ConvertToPoint3D(), endTemp.ConvertToPoint3D()) { ElementColor = Colors.Red };
-                line2.Name = levels[i];
-                db.Elements.Add(line2);
-                //加文字描述
-                var vertex = new GVertex();
-                vertex.Location = endTemp.ConvertToPoint3D();
-                vertex.Name = levels[i];
-                db.Elements.Add(vertex);      
-                #endregion
-
-                #region 画空间立面关系
-                //获取当前层的数据
-                var curData = td.FloorDatas.FirstOrDefault(t => t.LevelName == levels[i]);
-                if (curData == null) continue;
-                //空间标记不空
-                var theLevelSpaces = curData.EndPoints.Where(t => t.RoomFuncType != "").ToList();
-                #endregion
-                for (int j = 0; j < theLevelSpaces.Count; j++)
-                {
-                    index++;
-                    var x = start.X + index * 50;
-                    GetUpSpace(theLevelSpaces[j], new Point(x, start.Y), db, i, vseq, levels, td.FloorDatas);
-                }
-
-            }
-            return db;
-        }
-
-     
-
-        private void GetUpSpace(SgSpace space, Point start, GraphDB db, int level, double vseq, List<string> levelNames, List<FloorSpaceData> floorSpaces)
-        {
-            if (space.RoomFuncType == "") return;
-            var line2 = new GLine(start.ConvertToPoint3D(), new Point(start.X, start.Y +vseq).ConvertToPoint3D()) { ElementColor = Colors.Green };
-            db.Elements.Add(line2);
-;           var vertex = new GVertex();
-            vertex.Location = start.ConvertToPoint3D();
-            vertex.Name = Regex.Replace(space.Name, @"\s\d+", "");
-            db.Elements.Add(vertex);
-            if (space.UpElements.Count > 0)
-            {
-                var theSpace = space.UpElements.FirstOrDefault(t =>string.IsNullOrEmpty(t.Space.RoomFuncType));
-                if (theSpace == null) return;
-                level++;
-                //从上层数据中移除这个数据
-                var upFloorSpaces = floorSpaces.FirstOrDefault(t => t.LevelName == levelNames[level]);
-                //一级元素才存储UpElements才会有值,所以这里需要做一个转化
-
-                var upSpace = upFloorSpaces.EndPoints.FirstOrDefault(t => t.Id == theSpace.Space.Id);
-                if (upSpace != null)
-                {
-                    upFloorSpaces.EndPoints.Remove(upSpace);
-                    GetUpSpace(upSpace,new Point(line2.End.X,line2.End.Y), db, level, vseq, levelNames, floorSpaces);
-                }
-
-            }
-            else
-            {
-                //return;
-                level++;
-                if (level > levelNames.Count - 1) return;
-                //取出上层数据
-                var upFloorSpaces = floorSpaces.FirstOrDefault(t => t.LevelName == levelNames[level]);
-                if (upFloorSpaces == null)
-                {
-                    GetUpSpace(space, start, db, level, vseq, levelNames, floorSpaces);
-                }
-                else//根据轮廓进行比较
-                {
-                    //当前空间的轮廓与此层所有的空间轮廓进行比较
-                    var sgSpace = upFloorSpaces.EndPoints.Where(t => t.RoomFuncType == space.RoomFuncType).FirstOrDefault(t => JudgeTwoLineIntersect(t.BoundarySegment, space.BoundarySegment));
-                    if (sgSpace != null)
-                    {
-
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// 闭合区域,没有包含关系
-        /// </summary>
-        /// <param name="curve1"></param>
-        /// <param name="curve2"></param>
-        /// <returns></returns>
-        private bool JudgeTwoLineIntersect(List<List<Point>> close1, List<List<Point>> close2)
-        {
-            for (int i = 0; i < close1.Count - 1; i++)
-            {
-                for (int j = 0; j < close2.Count - 1; j++)
-                {
-                    if (JudgeTwoLineIntersect(close1[i], close2[j]))
-                    {
-                        return true;
-                    }
-                }
-            }
-
-            //TODO:判断是否包含,下面有点是否在闭合区域内
-            return false;
-        }
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="curve1"></param>
-        /// <param name="curve2"></param>
-        /// <returns></returns>
-        public bool JudgeTwoLineIntersect(List<Point> curve1, List<Point> curve2)
-        {
-            for (int i = 0; i < curve1.Count - 1; i++)
-            {
-                for (int j = 0; j < curve2.Count - 1; j++)
-                {
-                    if (JudgeTwoLineIntersect(curve1[i], curve1[i + 1], curve2[j], curve2[j + 1]))
-                    {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-        /// <summary>
-        /// 两条直线是否相交
-        /// </summary>
-        /// <param name="a"></param>
-        /// <param name="b"></param>
-        /// <param name="c"></param>
-        /// <param name="d"></param>
-        /// <returns></returns>
-        bool JudgeTwoLineIntersect(Point a, Point b, Point c, Point d)
-        {
-            /*
-            快速排斥:
-            两个线段为对角线组成的矩形,如果这两个矩形没有重叠的部分,那么两条线段是不可能出现重叠的
-            */
-            if (!(Math.Min(a.X, b.X) <= Math.Max(c.X, d.X) && Math.Min(c.Y, d.Y) <= Math.Max(a.Y, b.Y) && Math.Min(c.X, d.X) <= Math.Max(a.X, b.X) && Math.Min(a.Y, b.Y) <= Math.Max(c.Y, d.Y)))//这里的确如此,这一步是判定两矩形是否相交
-                                                                                                                                                                                                //1.线段ab的低点低于cd的最高点(可能重合) 2.cd的最左端小于ab的最右端(可能重合)
-                                                                                                                                                                                                //3.cd的最低点低于ab的最高点(加上条件1,两线段在竖直方向上重合) 4.ab的最左端小于cd的最右端(加上条件2,两直线在水平方向上重合)
-                                                                                                                                                                                                //综上4个条件,两条线段组成的矩形是重合的
-                                                                                                                                                                                                /*特别要注意一个矩形含于另一个矩形之内的情况*/
-                return false;
-            /*
-            跨立实验:
-            如果两条线段相交,那么必须跨立,就是以一条线段为标准,另一条线段的两端点一定在这条线段的两段
-            也就是说a b两点在线段cd的两端,c d两点在线段ab的两端
-            */
-            double u, v, w, z;//分别记录两个向量
-            u = (c.X - a.X) * (b.Y - a.Y) - (b.X - a.X) * (c.Y - a.Y);
-            v = (d.X - a.X) * (b.Y - a.Y) - (b.X - a.X) * (d.Y - a.Y);
-            w = (a.X - c.X) * (d.Y - c.Y) - (d.X - c.X) * (a.Y - c.Y);
-            z = (b.X - c.X) * (d.Y - c.Y) - (d.X - c.X) * (b.Y - c.Y);
-            return (u * v <= 0.00000001 && w * z <= 0.00000001);
-        }
-
         /// <summary>
         /// 空间分组信息
         /// </summary>

+ 6 - 31
MBI/SAGA.GplotDrawData/WinDrawSpace-Web.xaml.cs

@@ -38,26 +38,9 @@ namespace SAGA.GplotDrawData
 
             this.m_showType = showType;
             this.Loaded += WinDrawWaterNode_Loaded;
-            //ucShowElement.ComputerAction = () =>
-            //{
-            //    ComputerAction.Invoke();
-            //    WinDrawWaterNode_Loaded(null, null); //重新加载数据
-            //};
-
-            //ucShowElement.SaveAction = () =>
-            //{
-            //    RevitModelFileUpload.FileUpload();
-            //};
         }
         private bool IsRead = true;
-        private DataNode m_data;
-        private WallData m_wallData;
-
-        public WinDrawSpace_Web(DataNode node) : this()
-        {
 
-
-        }
         private void WinDrawWaterNode_Loaded(object sender, RoutedEventArgs e)
         {
             if (m_showType == GplotShowType.VerticalPlan)
@@ -72,9 +55,6 @@ namespace SAGA.GplotDrawData
             {
                 var node = GetSpaceData();
                 this.rootNode.ItemsSource = new List<DataNode>() { node };
-                m_data = node;
-                //读取墙数据
-                m_wallData = DrawDataServer.GetWallData();
             }
         }
         #region 立面空间处理
@@ -152,7 +132,7 @@ namespace SAGA.GplotDrawData
             DataNode root = new DataNode("空间关系");
             DataNode a = new DataNode("空间临接关系")
             {
-                Childrens = aData.FloorDatas.Select(f =>
+                Childrens = aData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
                 {
                     var dn = new DataNode(f.Name);
                     dn.SetData(f);
@@ -162,7 +142,7 @@ namespace SAGA.GplotDrawData
 
             DataNode t = new DataNode("建筑交通关系")
             {
-                Childrens = tData.FloorDatas.Select(f =>
+                Childrens = tData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
                 {
                     var dn = new DataNode(f.Name);
                     dn.SetData(f);
@@ -171,7 +151,7 @@ namespace SAGA.GplotDrawData
             };
             DataNode v = new DataNode("空气流通关系")
             {
-                Childrens = vData.FloorDatas.Select(f =>
+                Childrens = vData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
                 {
                     var dn = new DataNode(f.Name);
                     dn.SetData(f);
@@ -180,7 +160,7 @@ namespace SAGA.GplotDrawData
             };
             DataNode r = new DataNode("光照辐射关系")
             {
-                Childrens = rData.FloorDatas.Select(f =>
+                Childrens = rData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
                 {
                     var dn = new DataNode(f.Name);
                     dn.SetData(f);
@@ -189,15 +169,10 @@ namespace SAGA.GplotDrawData
             };
             root.Childrens.AddRange(new List<DataNode>() { a, t, v, r });
             return root;
-        }
-
-   
+        }   
         /// <summary>
         /// 外部命令启动计算
         /// </summary>
-        public Action ComputerAction;
-
-
-      
+        public Action ComputerAction;      
     }
 }

+ 178 - 0
MBI/SAGA.GplotManage/Command/ColdGplot/WinDrawSpace-Web.xaml.cs

@@ -0,0 +1,178 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+using CEFSharpWPF;
+using DrawData;
+using SAGA.DotNetUtils.Logger;
+using SAGA.MBI.Common;
+using SAGA.Models;
+
+namespace SAGA.GplotDrawData
+{
+    /// <summary>
+    /// WinDrawSpace_Web.xaml 的交互逻辑
+    /// </summary>
+    public partial class WinDrawSpace_Web : Window
+    {
+        public WinDrawSpace_Web()
+        {
+            InitializeComponent();
+            Vertex.SetRadius(6, 6);
+        }
+
+        private GplotShowType m_showType;
+        public WinDrawSpace_Web(GplotShowType showType) : this()
+        {
+
+            this.m_showType = showType;
+            this.Loaded += WinDrawWaterNode_Loaded;
+        }
+        private bool IsRead = true;
+
+        private void WinDrawWaterNode_Loaded(object sender, RoutedEventArgs e)
+        {
+            if (m_showType == GplotShowType.VerticalPlan)
+            {
+                //this.rootNode.Visibility = Visibility.Collapsed;
+                //grid.ColumnDefinitions[0].Width = new GridLength(0);
+                //DrawVSpaces();
+                InitVerticalSpaces();
+
+            }
+            else
+            {
+                var node = GetSpaceData();
+                this.rootNode.ItemsSource = new List<DataNode>() { node };
+            }
+        }
+        #region 立面空间处理
+        /// <summary>
+        /// 立面空间相关数据源
+        /// </summary>
+        private SpaceData VerticalSpaces { get; set; }
+        public void InitVerticalSpaces()
+        {
+            var spaceDatas = DrawDataServer.GetSpaceData(SpaceRelatedEnum.Crossing);
+            this.VerticalSpaces = spaceDatas;
+            InitVSpaceTree();
+        }
+        /// <summary>
+        /// 绘制立面空间
+        /// </summary>
+        private void DrawVSpaces(DataNode node)
+        {
+            if (node == null)
+                return;
+            //rootNode.Visibility = Visibility.Collapsed;
+            var spaceDatas = VerticalSpaces;// DrawDataServer.GetSpaceData(SpaceRelatedEnum.Crossing);
+            VirticalSpaceGraphView view = new VirticalSpaceGraphView();
+            view.SpaceType = node.Sno;
+            var db = view.CreateDb(spaceDatas);
+            ConstData.ResponseData = db.CreateJObjectGroup();
+            ucShowElement.Show(WebGplotSettings.VSpaceUrl);
+        }
+        public void InitVSpaceTree()
+        {
+            List<DataNode> dataNode = new List<DataNode>();
+          
+            dataNode.Add(new DataNode() { EName = "楼梯间",Sno="140" });
+            dataNode.Add(new DataNode() { EName = "中庭", Sno = "150" });
+            dataNode.Add(new DataNode() { EName = "竖井", Sno = "1B0" });
+            dataNode.Add(new DataNode() { EName = "其他公共区域", Sno = "1A0" });
+            this.rootNode.ItemsSource = dataNode;
+        }  
+        #endregion
+
+        private void RootNode_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
+        {
+            if (rootNode.SelectedItem is DataNode ln)
+            {
+                if (m_showType == GplotShowType.ViewPlan)
+                {
+                    if (ln.GetData<FloorSpaceData>() is FloorSpaceData fd)
+                        Draw(fd);
+                }
+                else
+                {
+                    DrawVSpaces(ln);
+                }
+              
+            }
+        }
+
+        void Draw(FloorSpaceData fd)
+        {
+            SpaceGraphView view = new SpaceGraphView();
+            var db = view.CreateDb(fd);
+            //db.SaveToFile(@"c:\space.json");
+            ConstData.ResponseData = db.CreateJObjectGroup();
+            ucShowElement.Show(WebGplotSettings.GplotUrl);    
+        }
+
+
+        private DataNode GetSpaceData()
+        {
+            var aData = DrawDataServer.GetSpaceData(SpaceRelatedEnum.All);
+            var tData = DrawDataServer.GetSpaceData(SpaceRelatedEnum.Crossing);
+
+            var vData = DrawDataServer.GetSpaceData(SpaceRelatedEnum.Ventilation);
+            var rData = DrawDataServer.GetSpaceData(SpaceRelatedEnum.Radiation);
+            DataNode root = new DataNode("空间关系");
+            DataNode a = new DataNode("空间临接关系")
+            {
+                Childrens = aData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
+                {
+                    var dn = new DataNode(f.Name);
+                    dn.SetData(f);
+                    return dn;
+                }).ToList()
+            };
+
+            DataNode t = new DataNode("建筑交通关系")
+            {
+                Childrens = tData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
+                {
+                    var dn = new DataNode(f.Name);
+                    dn.SetData(f);
+                    return dn;
+                }).ToList()
+            };
+            DataNode v = new DataNode("空气流通关系")
+            {
+                Childrens = vData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
+                {
+                    var dn = new DataNode(f.Name);
+                    dn.SetData(f);
+                    return dn;
+                }).ToList()
+            };
+            DataNode r = new DataNode("光照辐射关系")
+            {
+                Childrens = rData.FloorDatas.Reverse<FloorSpaceData>().Select(f =>
+                {
+                    var dn = new DataNode(f.Name);
+                    dn.SetData(f);
+                    return dn;
+                }).ToList()
+            };
+            root.Childrens.AddRange(new List<DataNode>() { a, t, v, r });
+            return root;
+        }   
+        /// <summary>
+        /// 外部命令启动计算
+        /// </summary>
+        public Action ComputerAction;      
+    }
+}

+ 80 - 0
MBI/SAGA.GplotManage/Command/ColdGplot/WinMachineRoomView-Web.xaml.cs

@@ -0,0 +1,80 @@
+using CEFSharpWPF;
+using SAGA.GplotDrawData.Draw;
+using SAGA.Models;
+using SAGA.RevitUtils.Windows;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+using SAGA.Models.Graphs;
+
+namespace SAGA.GplotDrawData
+{
+    /// <summary>
+    /// WinMachineRoomView_Web.xaml 的交互逻辑
+    /// </summary>
+    public partial class WinMachineRoomView_Web : WinBase
+    {
+        public WinMachineRoomView_Web()
+        {
+            InitializeComponent();
+        }
+        public Func<List<DocumentNode>> LoadData;
+        private ObservableCollection<DocumentNode> DocumentNodes { get; set; }
+        protected override void OnLoaded(object sender, RoutedEventArgs e)
+        {
+            base.OnLoaded(sender, e);
+
+            DocumentNodes = new ObservableCollection<DocumentNode>(this.LoadData?.Invoke() ?? new List<DocumentNode>());
+            this.TreeRootNode.ItemsSource = DocumentNodes;
+            //if (DocumentNodes.Any())
+            //{
+            //    SetSelectedItem(DocumentNodes[0].GetLeaves().FirstOrDefault() as DocumentNode);
+            //}
+        }
+        private void SetSelectedItem(DocumentNode node)
+        {
+            node.IsSelected = true;
+            node.IsExpanded = true;
+            var parent = node.Parent;
+            while (parent != null)
+            {
+                parent.IsExpanded = true;
+                parent = parent.Parent;
+            }
+
+            RootNode_OnSelectedItemChanged(null, null);
+        }
+
+        #region 事件相关
+        private void RootNode_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
+        {
+            if (TreeRootNode.SelectedItem is DocumentNode ln)
+            {
+                Draw(ln);
+            }
+        }
+        #endregion
+        private void Draw(DocumentNode docNode)
+        {
+            if (docNode?.Tag == null)
+                return;
+            //GplotDocument document = docNode.LinkDocument;
+            //RoomGraphView view = new RoomGraphView();
+            RoomGraphView2 view = new RoomGraphView2();
+            var db = view.CreateDb( docNode.Tag as List<GNodeGraph>);
+            ConstData.ResponseData = db.CreateJObjectGroup();
+            ucShowElement.Show(WebGplotSettings.GplotUrl);
+        }
+    }
+}

+ 0 - 1
MBI/SAGA.GplotRelationComputerManage/Command.cs

@@ -50,7 +50,6 @@ namespace SAGA.GplotRelationComputerManage
     {
         public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
         {
-
             #region 核心
             try
             {

+ 25 - 15
MBI/SAGA.GplotRelationComputerManage/ReadSpaceCommand.cs

@@ -12,6 +12,7 @@ using SAGA.MBI.DataArrange;
 using SAGA.MBI.Model;
 using SAGA.MBI.RequestData;
 using SAGA.Models;
+using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
 using Point = System.Windows.Point;
 
@@ -82,29 +83,38 @@ namespace SAGA.GplotRelationComputerManage
         {
             //缓存所有空间数据
             //查询所有设备
-             var str = new string[] { "Si" };//元空间为Si
-            List<JObject> datas = CommonConvert.QueryObjectInfoByTypes(str);
-            m_dicServerSpace = new Dictionary<string, JObject>();
-            datas.ForEach(t =>
-            {
-                var bimId = GetValue(t, "BIMID");
-                if (!string.IsNullOrEmpty(bimId))
-                {
-                    m_dicServerSpace[bimId] = t;
-                }
-
-            });
+            // var str = new string[] { "Si" };//元空间为Si
+            //List<JObject> datas = CommonConvert.QueryObjectInfoByTypes(str);
+            //m_dicServerSpace = new Dictionary<string, JObject>();
+            //datas.ForEach(t =>
+            //{
+            //    var bimId = GetValue(t, "BIMID");
+            //    if (!string.IsNullOrEmpty(bimId))
+            //    {
+            //        m_dicServerSpace[bimId] = t;
+            //    }
+
+            //});
             //打开所有楼层数据
+            //Stopwatch watch = new Stopwatch();
+            //watch.Start();
             var fileInfos = RevitModelPath.GetAllRevitFiles();//.Where(t => t.IndexOf("71062c") > -1);
+            SpaceComputerContext context = new SpaceComputerContext();
             foreach (var fileInfo in fileInfos)
             {
                 if (File.Exists(fileInfo))
                 {
-                    var uiApp = ExternalDataWrapper.Current.UiApp.Application;
-                    var doc = uiApp.OpenDocumentFile(fileInfo);   
-                    ComputerSpace(doc);
+                    //var uiApp = ExternalDataWrapper.Current.UiApp.Application;
+                   // var doc = uiApp.OpenDocumentFile(fileInfo);
+                    FloorSpaceItems floorItems = context.GetFloorItems(fileInfo);
+                    floorItems.Parse(context);
+                    floorItems.Document.Close();
+                    //ComputerSpace(doc);
                 }
             }
+            //MessageShow.Infomation((watch.ElapsedMilliseconds / 1000).ToString());
+            //watch.Stop();
+            //MessageShow.Infomation((watch.ElapsedMilliseconds / 1000).ToString());
         }
 
         /// <summary>

+ 5 - 1
MBI/SAGA.GplotRelationComputerManage/RevitModelPath.cs

@@ -26,9 +26,13 @@ namespace SAGA.GplotRelationComputerManage
             }
             if (FilePaths.Count == 0)
             {//TODO:有测试
+                List<string> files = new List<string>();
                 var projectFloors = DalModeFileManange.GetMissFileFloors(false);//.Where(t => t.Item.LocalName == "大师傅地方").ToList();
 
-                projectFloors.ForEach((tni) => GetFilePaths(tni, FilePaths));
+                projectFloors.ForEach((tni) => GetFilePaths(tni, files));
+                files.Reverse();
+                FilePaths = new List<string>(files);
+
             }
 
             return FilePaths;

+ 1 - 0
MBI/SAGA.GplotRelationComputerManage/SAGA.GplotRelationComputerManage.csproj

@@ -108,6 +108,7 @@
     <Compile Include="RevitSystemParse\Handler\SystemParseSetting.cs" />
     <Compile Include="RevitSystemParse\StartElementsManager.cs" />
     <Compile Include="SpaceEdgeInfo.cs" />
+    <Compile Include="SpaceRelation\ComputerSpaceItem.cs" />
     <Compile Include="SpaceRelation\FloorSpaceItems.cs" />
     <Compile Include="SpaceRelation\SpaceComputerContext.cs" />
     <Compile Include="SpaceRelation\SpaceComputerHandler.cs" />

+ 149 - 0
MBI/SAGA.GplotRelationComputerManage/SpaceRelation/ComputerSpaceItem.cs

@@ -0,0 +1,149 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:ComputerSpaceItem
+ * 作者:xulisong
+ * 创建时间: 2018/12/24 17:22:10
+ * 版本号: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.DotNetUtils.Extend;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+
+namespace SAGA.GplotRelationComputerManage
+{
+    /// <summary>
+    /// 计算相关信息
+    /// </summary>
+    public class ComputerSpaceItem
+    {
+        public ComputerSpaceItem(Space space)
+        {
+            this.Space = space;
+            this.BimId = space.GetBimId();
+            var mySegments = space.GetBoundarySegments(new SpatialElementBoundaryOptions());
+            OriginCurves = new List<Curve>();
+            var seg = mySegments.FirstOrDefault();
+            if (seg != null)
+            {
+                this.OriginCurves = mySegments[0].Select(s => s.GetCurve()).ToList();
+            
+            }
+            this.ZeroCurves = TransfomCurvesToZero(OriginCurves);
+        }
+        public Space Space { get; private set; }
+        /// <summary>
+        /// bimId
+        /// </summary>
+        public string BimId { get; set; }
+        /// <summary>
+        /// 空间功能类型
+        /// </summary>
+        public string FuncType { get; set; }
+        /// <summary>
+        /// 原始边框
+        /// </summary>
+        public List<Curve> OriginCurves { get; set; }
+        /// <summary>
+        /// 投影边框
+        /// </summary>
+        public List<Curve> ZeroCurves { get; set; }
+        /// <summary>
+        /// 标志是否被处理
+        /// </summary>
+        public bool IsHandled { get; set; }
+
+        #region 包围盒构件
+        private Outline m_Box;
+
+        public Outline Box
+        {
+            get
+            {
+                if (m_Box == null)
+                {
+                    List<double> listX = new List<double>();
+                    List<double> listY = new List<double>();
+                    ZeroCurves.ForEach(c =>
+                    {
+                        var listXYZ = new List<XYZ>(c.Tessellate());
+                        listXYZ.ForEach(xyz =>
+                        {
+                            listX.Add(xyz.X);
+                            listY.Add(xyz.Y);
+                        });
+                    });
+                    var tupleX = GetMaxMin(listX);
+                    var tupleY = GetMaxMin(listY);
+                    if (tupleX == null || tupleY == null)
+                    {
+                        m_Box = new Outline(XYZ.Zero,XYZ.Zero);
+                    }
+                    else
+                    {
+                        double coff = 1;//扩充误差
+                        m_Box = new Outline(new XYZ(tupleX.Item2 - coff, tupleY.Item2 - coff,0),new XYZ(tupleX.Item1 + coff, tupleY.Item1+ coff,0));
+                       
+                    }
+                    
+                }
+                return m_Box;
+            }
+        }
+
+        #endregion
+
+        #region 私有方法
+        private List<Curve> TransfomCurvesToZero(List<Curve> curves)
+        {
+            var zeroCurves = new List<Curve>();
+            if (curves != null)
+            {
+                var z = curves.FirstOrDefault()?.StartPoint()?.Z;
+                Transform tf = Transform.CreateTranslation(XYZ.Zero.NewZ(0 - z));
+                foreach (var curve in curves)
+                {
+                    zeroCurves.Add(curve.CreateTransformed(tf));
+                }
+            }
+            return zeroCurves;
+        }
+
+        /// <summary>
+        /// 取出集合的最大值和最小值Item1,最大值,Item2,最小值
+        /// </summary>
+        /// <param name="list"></param>
+        /// <returns></returns>
+        public Tuple<double, double> GetMaxMin(List<double> list)
+        {
+            if (list == null || !list.Any())
+            {
+                return null;
+            }
+            double min = list[0];
+            double max = list[0];
+            for (int i = 1; i < list.Count; i++)
+            {
+                var current = list[i];
+                if (current > max)
+                {
+                    max = current;
+                }
+
+                if (current < min)
+                {
+                    min = current;
+                }
+            }
+            return new Tuple<double, double>(max, min);
+        }
+
+        #endregion
+    }
+}

+ 364 - 13
MBI/SAGA.GplotRelationComputerManage/SpaceRelation/FloorSpaceItems.cs

@@ -9,14 +9,37 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Text.RegularExpressions;
 using Autodesk.Revit.DB;
 using Autodesk.Revit.DB.Mechanical;
 using FWindSoft.Data;
 using SAGA.DotNetUtils.Extend;
+using SAGA.MBI.DataArrange;
+using SAGA.MBI.Model;
+using SAGA.Models;
+using SAGA.RevitUtils;
 using SAGA.RevitUtils.Extends;
 
-namespace SAGA.GplotRelationComputerManage.SpaceRelation
+namespace SAGA.GplotRelationComputerManage
 {
+    [Flags]
+    public enum AdjanceElementType
+    {
+        None=0,
+        Wall=1,
+        VirtualWall=1<<1,
+        Door=1<<2,
+        Window=1<<3,
+        /// <summary>
+        /// 垂直邻接
+        /// </summary>
+        Vertical=1<<4,
+        /// <summary>
+        /// 垂直洞口,交通
+        /// </summary>
+        VerticalOpening = 1 << 5,
+    }
+
     /// <summary>
     ///模型解析对应的楼层空间数据
     /// </summary>
@@ -30,9 +53,11 @@ namespace SAGA.GplotRelationComputerManage.SpaceRelation
         public FloorSpaceItems(Document doc)
         {
             Document = doc;
-            Doors = new List<FamilyInstance>();
-            Windows = new List<FamilyInstance>();
+            Doors = new Dictionary<string, List<FamilyInstance>>();
+            Windows = new Dictionary<string, List<FamilyInstance>>();
             Spaces = new List<Space>();
+            ComputerSpaceItems = new List<ComputerSpaceItem>();
+            InitData();
         } 
         #endregion
 
@@ -44,30 +69,214 @@ namespace SAGA.GplotRelationComputerManage.SpaceRelation
         /// <summary>
         /// 关联门信息
         /// </summary>
-        public List<FamilyInstance> Doors { get; private set; }
+        public Dictionary<string,List<FamilyInstance>> Doors { get; private set; }
         /// <summary>
         /// 关联窗体信息
         /// </summary>
-        public List<FamilyInstance> Windows { get; private set; }
+        public Dictionary<string, List<FamilyInstance>> Windows { get; private set; }
         /// <summary>
         /// 关联空间信息
         /// </summary>
-        public List<Space> Spaces { get; private set; } 
+        public List<Space> Spaces { get; private set; }
+
+        /// <summary>
+        /// 空间计算数据
+        /// </summary>
+        public List<ComputerSpaceItem> ComputerSpaceItems { get; private set; }
         #endregion
 
+        private bool m_IsInited;
+        public void InitData()
+        {
+            if (!m_IsInited) 
+            {
+                var doc = Document;
+                Doors = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Doors).GroupBy(e =>
+                {
+                    var host = e.Host;
+                    if (host == null)
+                        return "-1";
+                    return host.Id.IntegerValue.ToString();
+                }).ToDictionary(g => g.Key, g => g.ToList());
+                Windows = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Windows).GroupBy(e =>
+                {
+                    var host = e.Host;
+                    if (host == null)
+                        return "-1";
+                    return host.Id.IntegerValue.ToString();
+                }).ToDictionary(g => g.Key, g => g.ToList());
+                Spaces = doc.GetElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).OfType<Space>().Where(s=>s.Area>0.001).ToList();
+                ComputerSpaceItems = Spaces.Select(s => new ComputerSpaceItem(s)).ToList();            
+                m_IsInited = true;
+            }          
+        }
+        #region 持久缓存数据
+        private Dictionary<string, SgSpace> m_SaveSpaces = new Dictionary<string, SgSpace>();
+
         /// <summary>
-        /// 解析
+        /// 获取空间持久数据【缓存没有的话,创建新对象,并加入缓存】
         /// </summary>
-        public void Parse()
+        /// <param name="space"></param>
+        /// <param name="context"></param>
+        /// <returns></returns>
+        public SgSpace GetSpace(Space space,SpaceComputerContext context)
         {
+            string key = space.GetBimId();
+            if (m_SaveSpaces.TryGetValue(key, out SgSpace useSpace))
+            {
+                return useSpace;
+            }
+            useSpace = context.NewSpace(space);
+            m_SaveSpaces[key] = useSpace;
+            return useSpace;
+        } 
+        #endregion
+        /// <summary>
+        /// 解析空间关系
+        /// </summary>
+        public void Parse(SpaceComputerContext context)
+        {
+            //初始化空间信息
+            Spaces.ForEach(s => GetSpace(s, context));
+
+            CurrentFloorParse(context);
+            UpFloorParse(context);
+            #region 保存缓存数据
             var doc = Document;
-            Doors = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Doors);
-            Windows = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Windows);
-            Spaces = doc.GetElements<SpatialElement>(BuiltInCategory.OST_MEPSpaces).OfType<Space>().ToList();
+            var id = Regex.Replace(doc.PathName, @".+\\(\w+)\\(\w+).rvt$", "$1-$2");
+            var saveName = DalProjectTree.GetFloorNameByFloorId(id.Split('-')[1]);
+            var levels = doc.GetLevels();
+            string levelName = saveName;
+            var currLevels = levels.FirstOrDefault(t => t.Name.IndexOf("-saga") > -1);
+            if (currLevels != null) levelName = currLevels.Name;
+            FloorSpaceData floorData = new FloorSpaceData
+            {
+                Name = saveName,
+                Id = id,
+                LevelName = levelName.Replace("-saga", "")
+            };
+            m_SaveSpaces.Values.ToList().ForEach(s => floorData.EndPoints.Add(s));
+            //获取标高名称,并按高度排序
+            List<string> levelNames = levels.OrderBy(t => t.Elevation).Where(t => Regex.IsMatch(t.Name, "[F|B]")).Select(t => t.Name.Replace("-saga", "")).ToList();
+            DrawDataServer.SaveSpaceFloorData(new List<FloorSpaceData>() { floorData }, levelNames);
+            #endregion
+        }
+        /// <summary>
+        /// 本层空间关系解析
+        /// </summary>
+        /// <param name="context"></param>
+        private void CurrentFloorParse(SpaceComputerContext context)
+        {
+            BinaryRelationCollection<Space, AdjanceElementType> spaceRelations =
+                new BinaryRelationCollection<Space, AdjanceElementType>(false,space=>space.Id.IntegerValue.ToString());
+            spaceRelations.SetSetting(new BinaryCollectionSetting<Space, AdjanceElementType>()
+                {UpdateAction = (o, n) => o.Value | n.Value});
+            #region 本层关系处理
             //展开空间关系数据
             var flatSpaceItems = FlatSpaceEdges(Spaces);
             var groupSpaces = flatSpaceItems.GroupBy(t => t.EdgeElement.Id.IntegerValue).ToList();
-            var relation = CalcCombineRelations(groupSpaces.ToList().Select(g=>g.Key).ToList());
+            var relations = CalcCombineRelations(groupSpaces.ToList().Select(g => g.Key).ToList());
+            for (int i = 0; i < groupSpaces.Count; i++)
+            {
+                var baseSpace = groupSpaces[i];
+                var rels = relations.Where(c => !c.IsHandled && c.Contains(baseSpace.Key)).ToList();
+                List<SpaceEdgeInfo> refEdgeInfos = new List<SpaceEdgeInfo>(baseSpace.ToList());
+                foreach (var rel in rels)
+                {
+                    rel.IsHandled = true;
+                    var anotherId = rel.GetAnother(baseSpace.Key);
+                    if (anotherId == baseSpace.Key)
+                    {
+                        continue;
+                    }
+                    var anSpace = groupSpaces.FirstOrDefault(g => g.Key == anotherId);
+                    if (anSpace != null)
+                    {
+                        refEdgeInfos.AddRange(anSpace.ToList());
+                    }
+                }
+                for (int j = 0; j < refEdgeInfos.Count; j++)
+                {
+                    var baseEdge = refEdgeInfos[j];
+                    for (int k =j + 1; k < refEdgeInfos.Count; k++)
+                    {
+                        var refEdge = refEdgeInfos[k];
+                        var type = JudgeAdjancentSpace(baseEdge, refEdge);
+                        if (type != AdjanceElementType.None)
+                        {
+                            BinaryRelationItem<Space, AdjanceElementType> item =
+                                new BinaryRelationItem<Space, AdjanceElementType>(baseEdge.Space, refEdge.Space)
+                                    { Value = type };
+                            spaceRelations.Update(item);
+                        }                  
+                    }
+                }
+            }
+            #endregion
+
+            #region 整理关联数据
+            foreach (var binaryItem in spaceRelations)
+            {
+                SpaceRelatedEnum relationType= SpaceComputerManager.GetRelationEnum(binaryItem.Value);
+                var space1 = GetSpace(binaryItem.First, context);
+                space1.AdjacentSpaces.Add(new AdjacentSpace() {Space = context.NewSpace(binaryItem.Second),RelatedEnum= relationType });
+                var space2 = GetSpace(binaryItem.Second, context);
+                space2.AdjacentSpaces.Add(new AdjacentSpace() { Space = context.NewSpace(binaryItem.First), RelatedEnum = relationType });
+            }
+            #endregion
+        }
+        /// <summary>
+        /// 上下层空间关系解析
+        /// </summary>
+        /// <param name="context"></param>
+        private void UpFloorParse(SpaceComputerContext context)
+        {
+            #region 上下层关系处理
+            /*1、从下往上计算,则可以利用现有缓存
+                2、如果上一层是夹层,则继续找夹层的上一层,。处理这层中没有分配上下关系的空间
+             */
+            var currentDoc = Document;
+            var currentSpaces = this.ComputerSpaceItems;
+            currentSpaces.ForEach(c => c.IsHandled = false);
+            do
+            {
+                var floorId = currentDoc.PathName.GetFileName();
+                var upFloor = DalProjectTree.GetUpperFloor(floorId);
+                if (upFloor == null)
+                    break;            
+                var upFloorItems = context.GetFloorItems(upFloor.FullPath);
+                if (upFloorItems == null)
+                    return;
+              
+                var upSpaces = upFloorItems.ComputerSpaceItems;
+                foreach (var currentSpace in currentSpaces)
+                {
+                    if (currentSpace.IsHandled)
+                        continue;
+                    var space1 = GetSpace(currentSpace.Space, context);
+                    foreach (var upSpace in upSpaces)
+                    {
+                        var type= JudgeUpAdjancentSpace(currentSpace, upSpace);
+                        if (type != AdjanceElementType.None)
+                        {
+                            currentSpace.IsHandled = true;
+                            SpaceRelatedEnum relationType = SpaceComputerManager.GetRelationEnum(type);
+                            var refSpace = context.NewSpace(upSpace.Space);
+                            space1.UpElements.Add(new AdjacentSpace() { Space = refSpace, RelatedEnum = relationType });
+                        }
+                    }
+                    
+                }
+                if (upFloor.FloorType == "4") //夹层为4
+                {
+                    currentDoc = upFloorItems.Document;
+                }
+                else
+                {
+                    break;
+                }
+            } while (true);           
+            #endregion
         }
 
         #region 展开空间与边界的关联关系
@@ -145,6 +354,7 @@ namespace SAGA.GplotRelationComputerManage.SpaceRelation
             var doc = Document;
             FilteredElementCollector collectors =
                 new FilteredElementCollector(doc, ids.Select(id => new ElementId(id)).ToList());
+            collectors.WhereElementIsNotElementType();
             var calcElements = collectors.ToElements();
             Dictionary<int, ElementGraphicItem> tempItems = new Dictionary<int, ElementGraphicItem>();
             for (int i = 0; i < calcElements.Count; i++)
@@ -173,7 +383,7 @@ namespace SAGA.GplotRelationComputerManage.SpaceRelation
                         if (((outItem.Width + inItem.Width) / 2.0d).IsThanEq(length))
                         {
                             relations.Add(new BinaryRelationItem<int>(outElement.Id.IntegerValue,
-                                outElement.Id.IntegerValue));
+                                inElement.Id.IntegerValue));
                         }
                     }
                     #endregion
@@ -234,5 +444,146 @@ namespace SAGA.GplotRelationComputerManage.SpaceRelation
         }
 
         #endregion
+
+        #region 邻接关系判断
+        /// <summary>
+        /// 判断两个空间,在指定边上的相交关系
+        /// </summary>
+        /// <param name="space1"></param>
+        /// <param name="space2"></param>
+        /// <returns></returns>
+        public AdjanceElementType JudgeAdjancentSpace(SpaceEdgeInfo space1, SpaceEdgeInfo space2)
+        {
+            var result=AdjanceElementType.None;
+            if(space1.Space.Id.IntegerValue==space2.Space.Id.IntegerValue)
+                return result;
+            /*先判断是否是虚拟墙。如果是实体墙,则进一步判断是否所有门窗之间的关系;
+               两个space,可能不是公用一个Eelment,而是通过关联产生的
+             */
+            //平行直线和弧线的投影
+            var baseCurve = space1.Edge;//spac1的edge和space2的edge平行
+            Curve curve1 = GetProjectCurve(baseCurve, space1.SegEdge);
+            Curve curve2 = GetProjectCurve(baseCurve, space2.SegEdge);
+            IntersectionResultArray ira;
+            var isConn = curve2.Intersect(curve1, out ira) != SetComparisonResult.Disjoint;
+            if (!isConn||(ira != null && ira.Size == 1))
+            {
+                 return result;
+            }           
+            #region 虚拟墙判断
+            var virType = typeof(ModelCurve);
+            if (space1.EType == virType && space2.EType == virType)
+            {
+                return AdjanceElementType.VirtualWall;
+            }
+            #endregion
+            result = AdjanceElementType.Wall;//必然墙相连
+            #region 门窗判断
+            List<Wall> walls = new List<Wall>();
+            foreach (var spaceEdgeInfo in new []{space1,space2})
+            {
+                if (spaceEdgeInfo.EType == typeof(Wall))
+                {
+                    if (walls.Any(w => w.Id == spaceEdgeInfo.EdgeElement.Id))
+                    {
+                        continue;
+                    }
+                    walls.Add(spaceEdgeInfo.EdgeElement as Wall);
+                }
+            }
+            if (walls.Any())
+            {
+                result = result | AdjanceElementType.Wall;
+                var doors = new List<FamilyInstance>();
+                var windows = new List<FamilyInstance>();
+                foreach (var wall in walls)
+                {
+                    List<FamilyInstance> tempDoors = new List<FamilyInstance>();
+                    if (Doors.TryGetValue(wall.Id.IntegerValue.ToString(), out tempDoors))
+                    {
+                        doors.AddRange(tempDoors);
+                    }
+                    List<FamilyInstance> tempWindows = new List<FamilyInstance>();
+                    if (Windows.TryGetValue(wall.Id.IntegerValue.ToString(), out tempWindows))
+                    {
+                        windows.AddRange(tempWindows);
+                    }
+                }          
+                List<Curve> edgeCurves = new List<Curve>() {space1.SegEdge, space2.SegEdge};
+                if (doors.Any(d => edgeCurves.All(c => c.IsContain(c.GetProjectPt(d.GetLocationPoint())))))
+                {
+                    result = result | AdjanceElementType.Door;
+                }
+                if (windows.Any(w => edgeCurves.All(c => c.IsContain(c.GetProjectPt(w.GetLocationPoint())))))
+                {
+                    result = result | AdjanceElementType.Window;
+                }
+            }
+           
+            #endregion
+          
+            return result;
+        }
+        /// <summary>
+        /// 获取Curve1在Curve2上的投影【两线为平行关系的直线和弧线】【可简化】
+        /// </summary>
+        /// <param name="projectCurve"></param>
+        /// <param name="curve"></param>
+        /// <returns></returns>
+        private Curve GetProjectCurve(Curve projectCurve, Curve curve)
+        {
+            var startPoint = projectCurve.GetProjectPt(curve.StartPoint());
+            var endPoint = projectCurve.GetProjectPt(curve.EndPoint());
+            if (projectCurve is Arc)
+            {
+                //弧形应该是法向投影
+                var middle = projectCurve.GetProjectPt((startPoint + endPoint) / 2);
+                return Arc.Create(startPoint, endPoint, middle);
+            }
+            return Line.CreateBound(startPoint, endPoint);
+        }
+        #endregion
+
+        #region 上下层关系判断
+        /// <summary>
+        /// 判断两个空间是否是上下相交关系
+        /// </summary>
+        /// <param name="aFSpace"></param>
+        /// <param name="bSpace"></param>
+        /// <returns></returns>
+        public AdjanceElementType JudgeUpAdjancentSpace(ComputerSpaceItem aFSpace, ComputerSpaceItem bSpace)
+        {
+            AdjanceElementType result = AdjanceElementType.None;
+            if (!aFSpace.Box.Intersects(bSpace.Box, 0))
+            {
+                return result;
+            }
+            if (ClosedIntersect(aFSpace.ZeroCurves, bSpace.ZeroCurves))
+            {
+                result = AdjanceElementType.Vertical;
+                if (SpaceComputerManager.IsCrossFunType(aFSpace.FuncType) && SpaceComputerManager.IsCrossFunType(bSpace.FuncType))
+                {
+                    result = result | AdjanceElementType.VerticalOpening;
+                }
+            }
+            return result;
+        }
+        public bool ClosedIntersect(List<Curve> closed1, List<Curve> closed2)
+        {
+            //判断所有的线是否有相交
+            foreach (var curve1 in closed1)
+            {
+                if (curve1.IsIntersectPoly(closed2)) return true;
+            }
+
+            //判断是否包含
+            foreach (var curve in closed1)
+            {
+                if (curve.StartPoint().PointInPolygon(closed2)) return true;
+            }
+
+            return closed2.Any(curve => curve.StartPoint().PointInPolygon(closed1));
+        }
+        #endregion
     }
 }

+ 80 - 0
MBI/SAGA.GplotRelationComputerManage/SpaceRelation/SpaceComputerContext.cs

@@ -7,17 +7,28 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Autodesk.Revit.DB.Mechanical;
 using Newtonsoft.Json.Linq;
+using SAGA.DotNetUtils.Extend;
 using SAGA.MBI.RequestData;
 using SAGA.Models;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
 
 namespace SAGA.GplotRelationComputerManage
 {
     public class SpaceComputerContext
     {
+        public SpaceComputerContext()
+        {
+            FloorItems =new Dictionary<string, FloorSpaceItems>();
+        }
+
         #region 空间信息
         /// <summary>
         /// 缓存空间对象
@@ -45,6 +56,75 @@ namespace SAGA.GplotRelationComputerManage
             m_Rooms.TryGetValue(bimId, out RoomItem resultItem);
             return resultItem;
         }
+
+        
+        /// <summary>
+        /// 创建空间持久数据
+        /// </summary>
+        /// <param name="space"></param>
+        /// <returns></returns>
+        public SgSpace NewSpace(Space space)
+        {
+            string key = space.GetBimId();
+            var roomItem = GetRoomItem(key);
+            var  useSpace = new SgSpace()
+            {
+                Id = space.Id.ToString(),
+                Name = space.Name,
+                Point = space.Location.GetPoint().ToW2DPoint(),
+
+            };
+            if (roomItem != null)
+            {
+                var display = roomItem.LocalName;
+                useSpace.Name = string.IsNullOrEmpty(display) ? space.Name : display;
+                useSpace.RoomFuncType = roomItem.RoomFuncType;
+            }
+            return useSpace;
+        }
+
         #endregion
+
+        #region 空间计算缓存信息
+        /// <summary>
+        /// 楼层空间数据缓存
+        /// </summary>
+        public Dictionary<string, FloorSpaceItems> FloorItems { get; private set; }
+
+        /// <summary>
+        /// 获取指定路径项目的楼层信息
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        public FloorSpaceItems GetFloorItems(string path)
+        {
+            var floorId = Path.GetFileNameWithoutExtension(path);
+            if (FloorItems.TryGetValue(floorId, out FloorSpaceItems floor))
+            {
+                return floor;
+            }
+
+            if (File.Exists(path))
+            {
+                var uiApp = ExternalDataWrapper.Current.UiApp.Application;
+                var doc = uiApp.OpenDocumentFile(path);
+                floor = new FloorSpaceItems(doc);
+                #region 初始化计算空间数据
+                floor.ComputerSpaceItems.ForEach(c =>
+                      {
+                          var room = GetRoomItem(c.BimId);
+                          if (room != null)
+                          {
+                              c.FuncType = room.RoomFuncType;
+                          }
+                      }); 
+                #endregion
+                FloorItems[floorId] = floor;
+            }
+            return floor;
+        }
+
+        #endregion
+
     }
 }

+ 49 - 3
MBI/SAGA.GplotRelationComputerManage/SpaceRelation/SpaceComputerManager.cs

@@ -10,6 +10,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using SAGA.Models;
 
 namespace SAGA.GplotRelationComputerManage
 {
@@ -21,13 +22,58 @@ namespace SAGA.GplotRelationComputerManage
     /// </summary>
     public class SpaceComputerManager
     {
+        private readonly static List<string> m_UpSpaceFunTypes= new List<string>() { "140","150","1A0","1B0" };
+     /// <summary>
+     /// 获取计算上下关系的空间类型
+     /// </summary>
+     /// <returns></returns>
+      public static List<string> GetUpSpaceFunTypes()
+       {
+            return m_UpSpaceFunTypes;  
+        }
+        /// <summary>
+        /// 是否是交通类型空间类型
+        /// </summary>
+        /// <param name="funType"></param>
+        /// <returns></returns>
+        public static bool IsCrossFunType(string funType)
+        {
+            return m_UpSpaceFunTypes.Contains(funType);
+        }
+
         /// <summary>
-        /// 获取计算上下关系的空间类型
+        /// 获取空间关系分类枚举
         /// </summary>
+        /// <param name="type"></param>
         /// <returns></returns>
-        public static List<string> GetUpSpaceFunTypes()
+        public static SpaceRelatedEnum GetRelationEnum(AdjanceElementType type)
         {
-            return new List<string>() { "140","150","1A0","1B0" };  
+            SpaceRelatedEnum result= SpaceRelatedEnum.Adjacent;//暂时先这么写,不会出现Type为None的关系
+            if (type == AdjanceElementType.None)
+                return result;         
+            if (type.HasFlag(AdjanceElementType.Wall))
+            {
+            }
+            if (type.HasFlag(AdjanceElementType.VirtualWall))
+            {
+                result = result | SpaceRelatedEnum.All;
+            }
+            if (type.HasFlag(AdjanceElementType.Door))
+            {
+                result = result | SpaceRelatedEnum.Crossing| SpaceRelatedEnum.Ventilation;
+            }
+            if (type.HasFlag(AdjanceElementType.Window))
+            {
+                result = result | SpaceRelatedEnum.Radiation | SpaceRelatedEnum.Ventilation;
+            }
+            if (type.HasFlag(AdjanceElementType.Vertical))
+            {
+            }
+            if (type.HasFlag(AdjanceElementType.VerticalOpening))
+            {
+                result = result | SpaceRelatedEnum.Crossing;
+            }
+            return result;
         }
     }
 }

+ 3 - 0
MBI/SAGA.Models/DrawDataServer.cs

@@ -129,6 +129,7 @@ namespace SAGA.Models {
             DbHelper.SaveAsFile(wd);
         }
         public static SpaceData GetSpaceData(SpaceRelatedEnum spaceRelated) {
+            //每次读取都是新的数据源
             SpaceData dn = DbHelper.FindOneByFile<SpaceData>();
             if (dn == null) return default(SpaceData);
 
@@ -143,6 +144,8 @@ namespace SAGA.Models {
                 foreach (var sgElement in fd.EndPoints) {
                     if (sgElement is SgSpace space) {
                         space.AdjacentSpaces = space.AdjacentSpaces.Where(Predicate).ToList();
+                        //垂直空间也处理
+                        space.UpElements = space.UpElements.Where(Predicate).ToList();
                     }
                 }
             }

+ 6 - 1
MBI/SAGA.Models/Graphs/GElement.cs

@@ -21,7 +21,7 @@ namespace SAGA.Models.Graphs
         /// <summary>
         /// 关联Id
         /// </summary>
-        public int Id { get; internal set; }
+        public string Id { get; internal set; }
         public string Name { get; set; } = string.Empty;
         /// <summary>
         /// 元素类型
@@ -33,5 +33,10 @@ namespace SAGA.Models.Graphs
         /// 关联数据
         /// </summary>
         public object RefData { get; set; }
+
+        public void SetId(string id)
+        {
+            Id = id;
+        }
     }
 }

+ 2 - 1
MBI/SAGA.Models/Graphs/GElementConverter.cs

@@ -63,7 +63,8 @@ namespace SAGA.Models.Graphs
                         var result = serializer.Deserialize(jObject.CreateReader(), useType);
                         if (result is GElement element)
                         {
-                            element.Id = Convert.ToInt32(jObject["Id"]?.ToString());
+                            //element.Id = Convert.ToInt32(jObject["Id"]?.ToString());
+                            element.Id = jObject["Id"]?.ToString();
                         }
                         return result;
                     }

+ 11 - 0
MBI/SAGA.RevitUtils/MBIExtension/MBIDocExtension.cs

@@ -11,6 +11,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
 using SAGA.RevitUtils.Extends;
 
 namespace SAGA.RevitUtils
@@ -28,5 +29,15 @@ namespace SAGA.RevitUtils
                       t.Name?.IndexOf("-saga") > -1 && t.ViewType == ViewType.FloorPlan);
             return view;
         }
+        /// <summary>
+        /// 获取element的BimId
+        /// </summary>
+        /// <param name="element"></param>
+        /// <returns></returns>
+        public static string GetBimId(this Element element)
+        {
+            var doc = element.Document;
+            return string.Format($"{doc.PathName.GetFileName()}:{element.Id.IntegerValue}");
+        }
     }
 }