/// <summary>
        /// 管道相交测试
        /// </summary>
        /// <param name="pipeLine">测试管道</param>
        /// <param name="isFirst">相交测试是一个递归的过程,在一层递归里面PipeLine并没有被实际创建,而是在测试结束后才创建,下面的递归
        /// 层,测试的管道都是已经被创建了的</param>
        /// <returns></returns>
        public Point3d? PipeLineCrossTest(PipeLine pipeLine)
        {
            Point3d? res;
            Dictionary<ObjectId, PipeLine> copyPipelines = new Dictionary<ObjectId, PipeLine>();
            foreach (var item in PipeLines)
            {
                copyPipelines.Add(item.Key, item.Value);
            }

            //和管道测试相交
            foreach (var item in copyPipelines)
            {
                PipeLine cItem = (PipeLine)item.Value;
                if (cItem == pipeLine)
                {
                    continue;
                }
                PipeLine.CrossType type = cItem.PipeLineCrossTest(pipeLine);
                if (type == PipeLine.CrossType.CrossNone)
                {
                    continue;
                }
                else if (type == PipeLine.CrossType.ParallelHead)
                {
                    Point3d p1 = pipeLine.Point(0);
                    Point3d p2 = pipeLine.Point(1);
                    Point3d p3;
                    bool result = false;
                    if ((p1 - cItem.Point(0)).Length < (p2 - cItem.Point(0)).Length)
                    {
                        result = false;
                        p3 = p2;
                    }
                    else
                    {
                        result = true;
                        p3 = p1;
                    }
                    Vector3d v = cItem.Point(0) - cItem.Point(1);
                    Vector3d v1 = p3 - cItem.Point(0);
                    Point3d p = cItem.Point(0) + v1.DotProduct(v.GetNormal()) * v.GetNormal();
                    //
                    pipeLine = new PipeLine(p, cItem.Point(1), false, this);
                    pipeLine.TailConnectedObject = cItem.TailConnectedObject;
                    if (pipeLine.TailConnectedObject != null)
                    {
                        pipeLine.TailConnectedObject.RemovePipeLine(cItem);
                        pipeLine.TailConnectedObject.AddPipeLine(pipeLine);
                    }
                    cItem.Delete();
                    //递归调用

                    res = PipeLineCrossTest(pipeLine);
                    if (result)
                    {
                        return null;
                    }
                    else
                    {
                        return res;
                    }
                }
                else if (type == PipeLine.CrossType.ParallelTail)
                {
                    Point3d p1 = pipeLine.Point(0);
                    Point3d p2 = pipeLine.Point(1);
                    Point3d p3;
                    bool result;
                    if ((p1 - cItem.Point(1)).Length < (p2 - cItem.Point(1)).Length)
                    {
                        result = false;
                        p3 = p2;
                    }
                    else
                    {
                        result = true;
                        p3 = p1;
                    }
                    Vector3d v = cItem.Point(1) - cItem.Point(0);
                    Vector3d v1 = p3 - cItem.Point(1);
                    Point3d p = cItem.Point(1) + v1.DotProduct(v.GetNormal()) * v.GetNormal();
                    //
                    pipeLine = new PipeLine(cItem.Point(0), p, false, this);
                    pipeLine.HeadConnectedObject = cItem.HeadConnectedObject;
                    if (pipeLine.HeadConnectedObject != null)
                    {
                        pipeLine.HeadConnectedObject.RemovePipeLine(cItem);
                        pipeLine.HeadConnectedObject.AddPipeLine(pipeLine);
                    }
                    cItem.Delete();
                    //递归调用
                    res = PipeLineCrossTest(pipeLine);
                    if (result)
                    {
                        return null;
                    }
                    else
                    {
                        return res;
                    }
                }
                else if (type == PipeLine.CrossType.NonParallelHead)
                {
                    Point3d p1 = pipeLine.Point(0);
                    Point3d p2 = pipeLine.Point(1);
                    Point3d p3;
                    bool result;
                    if ((p1 - cItem.Point(0)).Length < (p2 - cItem.Point(0)).Length)
                    {
                        result = false;
                        p3 = p2;
                    }
                    else
                    {
                        result = true;
                        p3 = p1;
                    }
                    SimplePipeJoint simplePipeJoint = new SimplePipeJoint(cItem.Point(1), cItem.Point(0), p3, PipeLine.GetScale() / 2, this, true);
                    cItem.UpdateStartPoint(simplePipeJoint.CalculateLastMlineEndPoint());
                    Point3d startPoint = simplePipeJoint.CalculateMlineStartPoint();
                    simplePipeJoint.AddPipeLine(cItem);
                    PipeLine newLine = new PipeLine(p3, startPoint, false, this);
                    simplePipeJoint.AddPipeLine(newLine);
                    cItem.HeadConnectedObject = simplePipeJoint;
                    newLine.TailConnectedObject = simplePipeJoint;
                    if (pipeLine.HeadConnectedObject != null)
                    {
                        pipeLine.HeadConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.HeadConnectedObject.AddPipeLine(newLine);
                        newLine.HeadConnectedObject = pipeLine.HeadConnectedObject;
                    }
                    //递归调用
                    res = PipeLineCrossTest(newLine);
                    if (result)
                    {
                        return null;
                    }
                    else
                    {
                        return res;
                    }
                }
                else if (type == PipeLine.CrossType.NonParallelTail)
                {
                    Point3d p1 = pipeLine.Point(0);
                    Point3d p2 = pipeLine.Point(1);
                    Point3d p3;
                    bool result;
                    if ((p1 - cItem.Point(1)).Length < (p2 - cItem.Point(1)).Length)
                    {
                        result = false;
                        p3 = p2;
                    }
                    else
                    {
                        result = true;
                        p3 = p1;
                    }
                    SimplePipeJoint simplePipeJoint = new SimplePipeJoint(cItem.Point(0), cItem.Point(1), p3, PipeLine.GetScale() / 2, this, true);
                    cItem.UpdateEndPoint(simplePipeJoint.CalculateLastMlineEndPoint());
                    cItem.TailConnectedObject = simplePipeJoint;
                    Point3d startPoint = simplePipeJoint.CalculateMlineStartPoint();
                    simplePipeJoint.AddPipeLine(cItem);
                    PipeLine newLine = new PipeLine(startPoint, p3, false, this);
                    simplePipeJoint.AddPipeLine(newLine);
                    newLine.HeadConnectedObject = simplePipeJoint;
                    if (pipeLine.TailConnectedObject != null)
                    {
                        pipeLine.TailConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.TailConnectedObject.AddPipeLine(newLine);
                        newLine.TailConnectedObject = pipeLine.TailConnectedObject;
                    }
                    res = PipeLineCrossTest(newLine);
                    if (result)
                    {
                        return null;
                    }
                    else
                    {
                        return res;
                    }
                }
                else if (type == PipeLine.CrossType.CrossHead)
                {
                    MultiPipeJoint mj = new MultiPipeJoint(this, true);
                    List<Point3d> ps = mj.GenerateFromCrossPipe(cItem, pipeLine.Point(0), pipeLine.Point(1), PipeLine.GetScale() / 2);
                    PipeLine p1 = new PipeLine(cItem.Point(0), ps[0], this, true);
                    PipeLine p2 = new PipeLine(ps[1], cItem.Point(1), this, true);
                    //
                    if (cItem.HeadConnectedObject != null)
                    {
                        cItem.HeadConnectedObject.RemovePipeLine(cItem);
                        cItem.HeadConnectedObject.AddPipeLine(p1);
                    }
                    if (cItem.TailConnectedObject != null)
                    {
                        cItem.TailConnectedObject.RemovePipeLine(cItem);
                        cItem.TailConnectedObject.AddPipeLine(p2);

                    }
                    p1.HeadConnectedObject = cItem.HeadConnectedObject;
                    p1.TailConnectedObject = mj;
                    p2.HeadConnectedObject = mj;
                    p2.TailConnectedObject = cItem.TailConnectedObject;

                    Point3d startPoint = ps[2];
                    cItem.Delete();

                    PipeLine pLine = new PipeLine(startPoint, pipeLine.Point(1), false, this);
                    pLine.HeadConnectedObject = mj;
                    if (pipeLine.TailConnectedObject != null)
                    {
                        pipeLine.TailConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.TailConnectedObject.AddPipeLine(pLine);
                        pLine.TailConnectedObject = pipeLine.TailConnectedObject;
                    }
                    mj.AddPipeLine(p1);
                    mj.AddPipeLine(p2);
                    mj.AddPipeLine(pLine);

                    res = PipeLineCrossTest(pLine);
                    return res;
                }
                else if (type == PipeLine.CrossType.CrossTail)
                {
                    //
                    MultiPipeJoint mj = new MultiPipeJoint(this, true);
                    List<Point3d> ps = mj.GenerateFromCrossPipe(cItem, pipeLine.Point(1), pipeLine.Point(0), PipeLine.GetScale() / 2);
                    PipeLine p1 = new PipeLine(cItem.Point(0), ps[0], this, true);
                    PipeLine p2 = new PipeLine(ps[1], cItem.Point(1), this, true);
                    //
                    if (cItem.HeadConnectedObject != null)
                    {
                        cItem.HeadConnectedObject.RemovePipeLine(cItem);
                        cItem.HeadConnectedObject.AddPipeLine(p1);
                    }
                    if (cItem.TailConnectedObject != null)
                    {
                        cItem.TailConnectedObject.RemovePipeLine(cItem);
                        cItem.TailConnectedObject.AddPipeLine(p2);
                    }
                    p1.HeadConnectedObject = cItem.HeadConnectedObject;
                    p1.TailConnectedObject = mj;
                    p2.HeadConnectedObject = mj;
                    p2.TailConnectedObject = cItem.TailConnectedObject;
                    Point3d startPoint = ps[2];
                    cItem.Delete();
                    PipeLine pLine = new PipeLine(pipeLine.Point(0), startPoint, false, this);
                    pLine.TailConnectedObject = mj;
                    if (pipeLine.HeadConnectedObject != null)
                    {
                        pipeLine.HeadConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.HeadConnectedObject.AddPipeLine(pLine);
                        pLine.HeadConnectedObject = pipeLine.HeadConnectedObject;
                    }
                    mj.AddPipeLine(p1);
                    mj.AddPipeLine(p2);
                    mj.AddPipeLine(pLine);
                    PipeLineCrossTest(pLine);
                    return mj.CenterPoint;
                }
                else if (type == PipeLine.CrossType.CrossOver)
                {
                    MultiPipeJoint mj = new MultiPipeJoint(this, true);
                    List<Point3d> ps = mj.GenerateFromCrossPipe(cItem, pipeLine.Point(1), pipeLine.Point(0), PipeLine.GetScale() / 2);
                    PipeLine p1 = new PipeLine(cItem.Point(0), ps[0], this, true);
                    PipeLine p2 = new PipeLine(ps[1], cItem.Point(1), this, true);
                    if (cItem.HeadConnectedObject != null)
                    {
                        cItem.HeadConnectedObject.RemovePipeLine(cItem);
                        cItem.HeadConnectedObject.AddPipeLine(p1);
                    }
                    if (cItem.TailConnectedObject != null)
                    {
                        cItem.TailConnectedObject.RemovePipeLine(cItem);
                        cItem.TailConnectedObject.AddPipeLine(p2);
                    }

                    p1.HeadConnectedObject = cItem.HeadConnectedObject;
                    p1.TailConnectedObject = mj;
                    p2.HeadConnectedObject = mj;
                    p2.TailConnectedObject = cItem.TailConnectedObject;

                    Point3d startPoint = ps[2];
                    cItem.Delete();

                    PipeLine pLine = new PipeLine(pipeLine.Point(0), startPoint, false, this);
                    pLine.TailConnectedObject = mj;
                    if (pipeLine.HeadConnectedObject != null)
                    {
                        pipeLine.HeadConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.HeadConnectedObject.AddPipeLine(pLine);
                        pLine.HeadConnectedObject = pipeLine.HeadConnectedObject;
                    }
                    mj.AddPipeLine(p1);
                    mj.AddPipeLine(p2);
                    mj.AddPipeLine(pLine);
                    PipeLineCrossTest(pLine);
                    //插入新的点
                    PipeLine se = mj.UpdateMultiJoint(pipeLine.Point(1));
                    se.HeadConnectedObject = mj;
                    if (pipeLine.TailConnectedObject != null)
                    {
                        pipeLine.TailConnectedObject.RemovePipeLine(pipeLine);
                        pipeLine.TailConnectedObject.AddPipeLine(se);
                        se.TailConnectedObject = pipeLine.TailConnectedObject;
                    }
                    res = PipeLineCrossTest(se);
                    return res;
                }

            }
            foreach (var item in SimplePipeJoints)
            {
                SimplePipeJoint pItem = (SimplePipeJoint)item.Value;
                if (pItem.PointInJoint(pipeLine.Point(0)) && !pItem.ConnectedPipes.Contains(pipeLine))
                {
                    MultiPipeJoint mpj = new MultiPipeJoint(this, true);
                    PipeLine ps = mpj.GenerateFromSimpleJoint(pItem, pipeLine.Point(1), PipeLine.GetScale() / 2);
                    ps.HeadConnectedObject = mpj;
                    res = PipeLineCrossTest(ps);
                    return res;
                }
                if (pItem.PointInJoint(pipeLine.Point(1)) && !pItem.ConnectedPipes.Contains(pipeLine))
                {
                    MultiPipeJoint mpj = new MultiPipeJoint(this, true);
                    PipeLine ps = mpj.GenerateFromSimpleJoint(pItem, pipeLine.Point(0), PipeLine.GetScale() / 2);
                    ps.TailConnectedObject = mpj;
                    res = PipeLineCrossTest(ps);
                    return null;
                }
            }
            foreach (var item in MultiPipeJoints)
            {
                MultiPipeJoint pItem = (MultiPipeJoint)item.Value;
                if (pItem.PointInJoint(pipeLine.Point(0)) && !pItem.ConnectedPipes.Contains(pipeLine))
                {
                    PipeLine se = pItem.UpdateMultiJoint(pipeLine.Point(1));
                    se.HeadConnectedObject = pItem;
                    res = PipeLineCrossTest(se);
                    return res;
                }
                if (pItem.PointInJoint(pipeLine.Point(1)) && !pItem.ConnectedPipes.Contains(pipeLine))
                {
                    PipeLine se = pItem.UpdateMultiJoint(pipeLine.Point(0));
                    se.HeadConnectedObject = pItem;
                    res = PipeLineCrossTest(se);
                    return null;
                }
            }
            pipeLine.SaveEntity();
            return pipeLine.Point(1);
        }
        public void restore()
        {
            isReStoring = true;
            if (Application.DocumentManager.MdiActiveDocument == null)
            {
                return;
            }
            Application.DocumentManager.MdiActiveDocument.Database.ObjectAppended -= Database_ObjectAppended;
            globalProperty = new GlobalProperty(true);
            Utility.ImportBlocks();
            BindEventListener();
            showSolution();
            BaseModel.ApplicationBaseModels.Clear();
            buildings.Clear();
            solutions.Clear();
            ToolPanel.changedEntityList.Clear();
            currentSolution = null;
            this.LoadMLineStyle();
            if (Application.DocumentManager.MdiActiveDocument == null)
            {
                return;
            }
            //先将所有注册的对象都清空!
            using (DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
            {
                globalProperty.Initialize();
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Editor   ed  = doc.Editor;
                Database db  = HostApplicationServices.WorkingDatabase;
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    //首先重建所有的Solution
                    LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForWrite, false);
                    foreach (ObjectId layerId in lt)
                    {
                        //设置图层颜色
                        LayerTableRecord            ltr   = (LayerTableRecord)trans.GetObject(layerId, OpenMode.ForWrite);
                        Dictionary <String, String> pairs = BaseModel.Load(layerId);
                        if (pairs != null && pairs.ContainsKey("type") && pairs["type"].CompareTo("solution") == 0)
                        {
                            ChromeTabItem chrometabitem = solutionPanel.chrometabs.RestoreTab(new System.Windows.Controls.Label(), false);
                            chrometabitem.CanDelete = true;
                            solutionPanel.AddCloseHandler(chrometabitem);
                            Solution solution = new Solution(false);
                            solution.ResetAttributes(pairs, layerId);
                            solution.RestoreAttributes();
                            solution.TabItem     = chrometabitem;
                            chrometabitem.Header = solution.SolutionName;
                            solutions.Add(solution);
                        }
                        else if (ltr.Name != "our_outline_layer" && (pairs == null || !pairs.ContainsKey("type")))
                        {
                            ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColor(System.Drawing.Color.Gray);
                        }
                    }
                    trans.Commit();
                    trans.Dispose();
                }
                using (Transaction trans1 = db.TransactionManager.StartTransaction())
                {
                    LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForWrite);
                    foreach (var layerid in lt)
                    {
                        LayerTableRecord ltr = (LayerTableRecord)layerid.GetObject(OpenMode.ForRead);
                        if (ltr.Name.Contains("outline_layer") || ltr.Name.Contains("方案"))
                        {
                            TypedValue[] tvs = new TypedValue[1] {
                                new TypedValue((int)DxfCode.LayerName, (ltr.Name))
                            };
                            SelectionFilter       sf  = new SelectionFilter(tvs);
                            PromptSelectionResult psr = ed.SelectAll(sf);
                            if (psr.Value != null)
                            {
                                foreach (var objectid in psr.Value.GetObjectIds())
                                {
                                    Dictionary <String, String> pairs = BaseModel.Load(objectid);
                                    if (pairs != null && pairs.ContainsKey("type"))
                                    {
                                        String type = pairs["type"];
                                        if (type.CompareTo(Building.modelType) == 0)
                                        {
                                            Building b = new Building(false);
                                            b.ResetAttributes(pairs, objectid);
                                            buildings.Add(objectid, b);
                                        }
                                        else if (type.CompareTo(HeatProducer.modelType) == 0)
                                        {
                                            var b = new HeatProducer();
                                            b.ResetAttributes(pairs, objectid);
                                        }
                                        else if (type.CompareTo(SubStation.modelType) == 0)
                                        {
                                            var b = new SubStation();
                                            b.ResetAttributes(pairs, objectid);
                                        }

                                        else if (type.CompareTo(PipeLine.modelType) == 0)
                                        {
                                            var b = new PipeLine();
                                            b.ResetAttributes(pairs, objectid);
                                            b.RetriveMline();
                                        }
                                        else if (type.CompareTo(District.modelType) == 0)
                                        {
                                            var d = new District();
                                            d.ResetAttributes(pairs, objectid);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    trans1.Dispose();
                }
                using (Transaction trans2 = db.TransactionManager.StartTransaction())
                {
                    //然后遍历所有的管道结头
                    DBDictionary groups = trans2.GetObject(db.GroupDictionaryId, OpenMode.ForRead) as DBDictionary;
                    foreach (DBDictionaryEntry entry in groups)
                    {
                        ObjectId objId = entry.Value;
                        Dictionary <String, String> pairs = BaseModel.Load(objId);
                        if (pairs != null && pairs.ContainsKey("type"))
                        {
                            string type = pairs["type"];
                            if (type.CompareTo(SimplePipeJoint.modelType) == 0)
                            {
                                var b = new SimplePipeJoint();
                                b.ResetAttributes(pairs, objId);
                                b.Retrive();
                            }
                            if (type.CompareTo(MultiPipeJoint.modelType) == 0)
                            {
                                var b = new MultiPipeJoint();
                                b.ResetAttributes(pairs, objId);
                                b.Retrive();
                            }
                        }
                        // }
                    }
                    trans2.Dispose();
                }
                foreach (var item in BaseModel.ApplicationBaseModels)
                {
                    item.Value.RestoreAttributes();
                }

                if (globalProperty.ActiveTab == -1 || globalProperty.ActiveTab == 0)
                {
                    solutionPanel.SelectOutLineLayer();
                    HeatSourceLayoutApp.currentSolution = null;
                }
                else
                {
                    foreach (var i_solution in solutions)
                    {
                        if (i_solution.SId == globalProperty.ActiveTab)
                        {
                            solutionPanel.chrometabs.ChangeSelectedItem(i_solution.TabItem);
                            HeatSourceLayoutApp.currentSolution = i_solution;
                            break;
                        }
                    }
                }
            }
            isReStoring = false;
            Application.DocumentManager.MdiActiveDocument.Database.ObjectAppended += Database_ObjectAppended;
        }