cloudflight
2024-08-03 5dde4212e3a73bf1ab0fd9e4d34dfebad0f8ffa2
Hydraulic/Hydro.MapUI/Map/MapViewer.cs
@@ -1,12 +1,16 @@
//using CloudWaterNetwork.Magnifier;
using DevExpress.XtraEditors;
using Hydro.CommonBase;
using Hydro.Core.Model;
using Hydro.Inp;
using Hydro.MapUI.WindowsForm;
//using ConfigApp;
//using DevExpress.Diagram.Core.Layout;
//using DevExpress.DirectX.NativeInterop.Direct2D;
//using DevExpress.Utils.Extensions;
//using dict_py_Inner;
using Hydro.MapView;
using Hydro.MapView.Base;
using Hydro.MapView.Common;
using Newtonsoft.Json;
//using ReflectionManager_NameSpace;
@@ -27,6 +31,7 @@
using System.Runtime.Remoting.Metadata;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
@@ -132,6 +137,10 @@
            BackColor = Color.Transparent;
        }
        public void SetEditMode(bool isEditMode)
        {
            _IsEditMode= isEditMode;
        }
        private void MapViewer_Load(object sender, EventArgs e)
        {
            this.panel1.Visible = _showToolBar;
@@ -161,10 +170,64 @@
            cb_Link_Colour.SelectedIndex = 0;
            map.Init(TC,new DrawDelegate[] { Draw, Draw, DrawH },new MouseDelegate[] { mapMouseDown, mapMouseMove, mapMouseUp, mapMouseWheel });
            map.Init(TC,new DrawDelegate[] { Draw, Draw, DrawBackGroud, DrawH },new MouseDelegate[] { mapMouseDown, mapMouseMove, mapMouseUp, mapMouseWheel });
            TContainer TCCube = new TContainer();
            TCCube.template = new Template();
            TCCube.template.network = new MapViewNetWork();
            TCCube.template.network.Areas = new List<AreaViewModel>();
            Cube cb=new Cube();
            foreach (var item in cb.FacesVertices)
            {
                AreaViewModel area = new AreaViewModel();
                area.ID = item.Key.ToString();
                area.InnerNodes = new List<NodeViewModel>();
                //area.Name= item.Key.ToString();
                //6个面设置不一样的颜色
                switch (item.Key)
                {
                    case 1:
                        area.color = Color.Red;
                        area.Name = "右";
                        break;
                    case 2:
                        area.color = Color.SkyBlue;
                        area.Name = "左";
                        break;
                    case 3:
                        area.color = Color.Green;
                        area.Name = "后";
                        break;
                    case 4:
                        area.color = Color.DarkBlue;
                        area.Name = "前";
                        break;
                    case 5:
                        area.color = Color.Purple;
                        area.Name = "上";
                        break;
                    case 6:
                        area.color = Color.Orange;
                        area.Name = "下";
                        break;
                    default:
                        area.color = Color.White;
                        break;
                }
                foreach (var p in item.Value)
                {
                    NodeViewModel node = new NodeViewModel();
                    node.X = p.X;
                    node.Y = p.Y;
                    node.Elev = p.Z;
                    area.InnerNodes.Add(node);
                }
                TCCube.template.network.Areas.Add(area);
            }
            CubeView.Init(TCCube, new DrawDelegate[] { Draw, Draw, DrawBackGroud, DrawH }, new MouseDelegate[] { CubeViewMouseDown, CubeViewMouseMove, CubeViewMouseUp, mapMouseWheel });
        }
@@ -388,141 +451,7 @@
                __needpaintall = value;
            }
        }
        //protected override void OnPaint(PaintEventArgs e)
        //{
        //    base.OnPaint(e);
        //    if (float.IsInfinity(zoom)) return;
        //    //label_center.Text = $"center:({MapCenter.X.ToString("0.00")} ,{MapCenter.Y.ToString("0.00")})";
        //    //label_zoom.Text = $"Zoom:{zoom.ToString("0.000")}";
        //    //toolStripStatusLabel_rotation.Text = $"Rotation:({Rotation.ToString("0")},{RotationF.ToString("0")})";
        //    //if (!_needPaintAll)
        //    //    return;
        //    int heightOfBar = showToolBar ? 24 : 0;
        //    if (!showToolBar) heightOfBar = 0;
        //    if (e.ClipRectangle != new Rectangle(this.Left, heightOfBar, this.map.Width, this.map.Height - heightOfBar - statusStrip1.Height)) return;
        //    _needPaintAll = false;
        //    if (buffer == null || buffer.Width != Width || buffer.Height != Height)
        //    {
        //        buffer?.Dispose();
        //        buffer = new Bitmap(Width, Height);
        //    }
        //    // 使用缓存绘制,避免在每次重绘时重新计算所有要绘制的元素
        //    //if (bufferG == null) bufferG = Graphics.FromImage(buffer);
        //    using (var bufferG = Graphics.FromImage(buffer))
        //    //using (var bufferG = e.Graphics)
        //    {
        //        // 先将控件的背景填充为白色
        //        bufferG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        //        bufferG.Clear(Color.Transparent);
        //        bufferG.TranslateTransform(Width / 2, Height / 2);
        //        bufferG.ScaleTransform(Zoom.X, Zoom.Y);
        //        bufferG.TranslateTransform(-MapCenter.X, -MapCenter.Y);
        //        //if (_NodeColour==null)
        //        //{
        //        //    cb_Node_Colour_SelectedIndexChanged(1, new EventArgs());
        //        //}
        //        //if (_LinkColour==null)
        //        //{
        //        //    cb_Link_Colour_SelectedIndexChanged(1, new EventArgs());
        //        //}
        //        //BookMark    :绘制地图事件
        //        Draw(bufferG, _Template);
        //        if (_newTemplate?.network != null) Draw(bufferG, _newTemplate);
        //        var r = 2f / zoom;
        //        if (_isDragging && DragStartPos!=new PointF(0,0) && mousePosition!=new PointF(0,0))
        //        {
        //            label_center.Text = $"S:{DragStartPos.X}:{DragStartPos.Y} E:{mousePosition.X}:{mousePosition.Y}";
        //            var _lastMousePosition = DragStartPos;
        //            // 绘制矩形
        //            var start = new PointF((float)Math.Min(mousePosition.X, _lastMousePosition.X), (float)Math.Min(mousePosition.Y, _lastMousePosition.Y));
        //            var size = new SizeF((float)Math.Abs(_lastMousePosition.X - mousePosition.X), (float)Math.Abs(_lastMousePosition.Y - mousePosition.Y));
        //            if (size.Width == 0) size.Width = 0.01f;
        //            if (size.Height == 0) size.Height = 0.01f;
        //            var rectangle0 = new RectangleF(start, size);
        //            using (var pen = new Pen(Color.Black, 0.5f * r))
        //            {
        //                bufferG.DrawRectangles(pen, new RectangleF[] { rectangle0 });
        //            }
        //        }
        //        if (_isPainting)
        //        {
        //            if (_mouseState == MouseState.新增立管)
        //            {
        //                var wPos=GetZZWorldPoint(_select_junction1.Position3D, _MousePosition,new Vector3(0,0,1));
        //                using (var pen = new Pen(Color.Black, 1 * r))
        //                {
        //                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
        //                    bufferG.DrawLine(pen, WorldPointToMapPoint(_select_junction1), WorldPointToMapPoint(wPos));
        //                }
        //            }
        //            else
        //            {
        //                using (var pen = new Pen(Color.Black, 1 * r))
        //                {
        //                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
        //                    bufferG.DrawLine(pen, WorldPointToMapPoint(_select_junction1), _MousePosition);
        //                }
        //            }
        //        }
        //        if (_isDrawingPolygon && polygonPoints.Count > 0)
        //        {
        //            List<PointF> pf = polygonPoints.ToList();
        //            pf.Add(new PointF(mousePosition.X, mousePosition.Y));
        //            using (var pen = new Pen(Color.Black, 1 * r))
        //            {
        //                // 绘制多边形虚线边框
        //                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
        //                bufferG.DrawLines(pen, pf.ToArray());
        //            }
        //        }
        //        if (_isSettingBackGroundPictur)
        //        {
        //            var _lastMousePosition = DragStartPos;
        //            // 绘制矩形
        //            var start = new PointF((float)Math.Min(mousePosition.X, _lastMousePosition.X), (float)Math.Min(mousePosition.Y, _lastMousePosition.Y));
        //            var size = new SizeF((float)Math.Abs(_lastMousePosition.X - mousePosition.X), (float)Math.Abs(_lastMousePosition.Y - mousePosition.Y));
        //            var rectangle0 = new RectangleF(start, size);
        //            using (var pen = new Pen(Color.Black, 1 * r))
        //            {
        //                bufferG.DrawRectangles(pen, new RectangleF[] { rectangle0 });
        //            }
        //        }
        //        if (_isMovingObject)
        //        {
        //            var newP = _MousePosition;
        //            //var p = MapPointToWorldPoint(, _OperaNode.Elev);
        //            var oldP3D = (PointF3D)_undoOldValue;
        //            var oldP = WorldPointToMapPoint(new PointF(oldP3D.X, oldP3D.Y), oldP3D.Z);
        //            List<PointF> pf = new List<PointF> { oldP, newP };
        //            using (var pen = new Pen(Color.Black, 1 * r))
        //            {
        //                // 绘制多边形虚线边框
        //                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
        //                bufferG.DrawLines(pen, pf.ToArray());
        //            }
        //        }
        //    }
        //    // 将生成的画布绘制到控件上
        //    e.Graphics.DrawImage(buffer, 0, 0);
        //}
        PointF[] getCurclePoints(int num)
        {
@@ -547,9 +476,13 @@
        private void timer_draw_Tick(object sender, EventArgs e)
        {
            _mouseHoverCheckFlag = true;
            if (_timerDraw)
            if (_timerDraw && map.Status==DrawingStatus.Ready)
            {
                this.map.Invalidate();
            _timerDraw = false;
                this.CubeView.Invalidate();
                _timerDraw = false;
            }
        }
        protected override void OnResize(EventArgs e)
@@ -623,7 +556,7 @@
                }
                //移动
                if (selectedObjs.Count >= 1) //&& selectedObjs[0].isNode())
                if (_IsEditMode && selectedObjs.Count >= 1) //&& selectedObjs[0].isNode())
                {
                    List<NodeViewModel> nodes = selectedNodes;
                    foreach (NodeViewModel node in nodes)
@@ -752,7 +685,7 @@
                //    Math.Abs((int)DragStartPos.Y - (int)MP.Y));
                //DrawSelectionRect(selectionRect);
                needInvalidate = true;
            }
            else if (_isRotating)
            {
@@ -786,7 +719,7 @@
                // 遍历所有对象,找出范围内的对象
                PointF clickedPoint = new PointF(e.X, e.Y);  //ScreenToMap(new PointF(e.X, e.Y));
                var obj = GetObj_by_ScreenPoint(clickedPoint);
                if (hoveredObjs.Count > 0 && hoveredObjs[0] == obj || hoveredObjs.Count==0 && obj==null)
                if (hoveredObjs.Count > 0 && hoveredObjs[0] == obj || hoveredObjs.Count == 0 && obj == null)
                {
                    //needInvalidate = false;
                }
@@ -795,18 +728,18 @@
                    needInvalidate = true;
                    hoveredObjs.ForEach(o => o.Hovered = false);
                    hoveredObjs.Clear();
                    if (obj!=null)
                    if (obj != null)
                    {
                        obj.Hovered = true;
                        hoveredObjs.Add(obj);
                    }
                }
            }
            if (needInvalidate) this.SetMapInvalidate();
@@ -932,7 +865,8 @@
            }
            if  /*插入结构*/(e.Button == MouseButtons.Left && _isInsertingObject)
            {
                var net = _newTemplate.network;
                var net = _newTemplate.network;//clone
                var net0 = _newTemplate.network.DeepCopyByBin<MapViewNetWork>();
                List<NodeViewModel> nodes = _Nodes.Select(node => (NodeViewModel)node).ToList();
                float minDist = 100f;
                NodeViewModel minNode = null;
@@ -957,7 +891,7 @@
                    var p1 = (PointF3D)_undoOldValue;
                    var p2 = minNode.Position3D;
                    var dd = _newTemplate.OffSet;
                    //var dd = _newTemplate.OffSet;
                    dx = p2.X - p1.X;
                    dy = p2.Y - p1.Y;
                    dz = p2.Z - p1.Z;
@@ -988,7 +922,7 @@
                var list = _Network.Add(net);
                var j = _Network.AddPipe(minNode, _OperaNode);
                j.Length = 0.0001f;
                //j.Length = 0.0001f;
                list.Add(j);
                _OperaNode = null;
                _NewNet.Clear();
@@ -1002,12 +936,18 @@
                selectedObjs.AddRange(list);
                MapObjectExtensions.AddCommand(_Network, "Add", null, list);
                _isInsertingObject = false;
                //_OperaNode = null;
                //_Network.Nodes.AddRange(net.Nodes);
                //_Network.Links.AddRange(net.Links);
                _newTemplate.network = net0;
                _isInsertingObject = true;
                _undoOldValue = new PointF3D(0, 0, 0);
                _OperaNode = _newTemplate.network.Nodes.Find(node => node.ID == _newTemplate.Node1) as NodeViewModel;
                SetMapInvalidate();
                return;
            }
@@ -1077,7 +1017,7 @@
                    var l = new List<IBaseViewModel>();
                    l.Add(_Network.AddPipe(_OperaNode, minNode));
                    if (l.Count > 0) MapObjectExtensions.AddCommand(_Network, "Add", null, l);
                    _OperaNode = null;
                    _NewNet.Clear();
                }
@@ -1152,7 +1092,7 @@
                    case MouseState.新建重复器:
                        if (_select_junction1 == null)
                        {
                            if (_mouseState==MouseState.新增立管)
                            if (_mouseState == MouseState.新增立管)
                            {
                                var m = ScreenToVMap(new PointF(e.X, e.Y));
                                z = m.Y;
@@ -1164,19 +1104,19 @@
                                getPointAndHeight(e, out p, out z);
                                Set_junction1(e);
                            }
                        }
                        else
                        {
                            if (_mouseState == MouseState.新增立管)
                            {
                                //需要把鼠标位置转换为立管的位置,获取鼠标位置的高程
                                var wPos = GetZZWorldPoint(_select_junction1.Position3D, _MousePosition, new Vector3(0, 0, 1));
                                //var m = ScreenToVMap(new PointF(e.X, e.Y));
                                //z = m.Y;
                                p = new PointF(wPos.X, wPos.Y);
                                var l = AddLink(new PointF( e.X,e.Y), true, p, wPos.Z);
                                var l = AddLink(new PointF(e.X, e.Y), isdoubleClick, p, wPos.Z);
                                if (l.Count > 0) MapObjectExtensions.AddCommand(_Network, "Add", null, l);
                            }
                            else
@@ -1191,14 +1131,14 @@
                                }
                                else
                                {
                                    getPointAndHeight(e, _select_junction1, out p, out z);
                                    var l = AddLink(new PointF(e.X, e.Y), isdoubleClick, p,z);
                                    getPointAndHeight(e, _select_junction1, out p, out z);
                                    var l = AddLink(new PointF(e.X, e.Y), isdoubleClick, p, z);
                                    if (l.Count > 0) MapObjectExtensions.AddCommand(_Network, "Add", null, l);
                                }
                            }
                        }
                        break;
                }
@@ -1466,8 +1406,11 @@
                    if (!isMouseMoved)
                    {
                        右键_Menu.Show(this, e.Location);
                        转换为ToolStripMenuItem.Enabled = selectedNodes.Count > 0; //(selectedObjs.Count == 1);
                        删除ToolStripMenuItem.Enabled = selectedObjs.Count > 0;
                        删除ToolStripMenuItem1.Enabled = selectedObjs.Count > 0;
                    }
                    if (recordView) MapObjectExtensions.AddCommand(mapOption, "Map", mapOption0, mapOption);
@@ -1549,6 +1492,7 @@
                    obj = link;
                }
            }
            return obj;
        }
@@ -1614,6 +1558,194 @@
        private int _lastMouseX;
        private int _lastMouseY;
        #endregion
        #region CubeView鼠标事件
        void CubeViewMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            _ClickStartPos = new PointF(e.X, e.Y);
            DragStartPos = ScreenToMap(new PointF(e.X, e.Y));
            mousePosition = _MousePosition = ScreenToMap(new PointF(e.X, e.Y));
            if (e.Button == MouseButtons.Left && _isInsertingObject)
            {
            }
            else if (e.Button == MouseButtons.Left && _mouseState == MouseState.无)
            {
            }
            else if (e.Button == MouseButtons.Left && _mouseState == MouseState.设置底图范围)
            {
            }
            else if (e.Button == MouseButtons.Right)
            {
                RotaStartPos = new PointF(e.X, e.Y);
                Rotation0 = Rotation;
                俯视角度_start = RotationF;
                _lastCursor = this.Cursor;
                Cursor = Cursors.Hand;
                mapOption0 = mapOption.Copy();
                _isRotating = true;
            }
        }
        void CubeViewMouseMove(MouseEventArgs e)
        {
            //base.OnMouseMove(e);
            bool needInvalidate = false;
            _MousePosition = ScreenToMap(new PointF(e.X, e.Y));
            if (_isRotating)
            {
                mousePosition = _MousePosition;
                bool is下半屏幕 = RotaStartPos.Y >= this.map.Height / 2;
                if (ModifierKeys != Keys.Alt) Rotation = Rotation0 + ((float)e.X - (float)RotaStartPos.X) * 180 * 2.5 / (float)this.map.Width * (is下半屏幕 ? 1 : 1);
                if (ModifierKeys != Keys.Shift) RotationF = 俯视角度_start + ((float)e.Y - (float)RotaStartPos.Y) * 180 * 2.5 / (float)this.map.Height;
                if (RotationF > 90) RotationF = 90;
                if (RotationF < 0) RotationF = 0;
                needInvalidate = true;
            }
            //else
            /*判断是否触碰到对象*/
            if (_mouseHoverCheckFlag)
            {
                _mouseHoverCheckFlag = false;
                // 遍历所有对象,找出范围内的对象
                PointF clickedPoint = new PointF(e.X, e.Y);  //ScreenToMap(new PointF(e.X, e.Y));
                var obj = GetObj_by_ScreenPoint(clickedPoint);
                if (hoveredObjs.Count > 0 && hoveredObjs[0] == obj || hoveredObjs.Count == 0 && obj == null)
                {
                    //needInvalidate = false;
                }
                else
                {
                    needInvalidate = true;
                    hoveredObjs.ForEach(o => o.Hovered = false);
                    hoveredObjs.Clear();
                    if (obj != null)
                    {
                        obj.Hovered = true;
                        hoveredObjs.Add(obj);
                    }
                }
            }
            if (needInvalidate) this.SetMapInvalidate();
            label_mouse.Text = $"X:{e.X.ToString("0")} Y:{e.Y.ToString("0")} [Map]X:{_MousePosition.X.ToString("0.00")} Y:{_MousePosition.Y.ToString("0.00")}";
            _lastMouseX = e.X;
            _lastMouseY = e.Y;
        }
        void CubeViewMouseUp(MouseEventArgs e)
        {
            //BookMark    :鼠标抬起事件
            base.OnMouseUp(e);
            bool isMouseMoved = Get_dist(_ClickStartPos, new PointF(e.X, e.Y)) > 10;
            bool isdoubleClick = (DateTime.Now - _lastMouseUp).TotalMilliseconds <= doubleClick_Delay;
            _lastMouseUp = DateTime.Now;
            if /*点选*/(!isMouseMoved && _mouseState == MouseState.无 && e.Button == MouseButtons.Left && ModifierKeys == Keys.None)
            {
                _isDragging = false;
                // 遍历所有点,找出最近的点
                PointF clickedPoint = new PointF(e.X, e.Y);  //ScreenToMap(new PointF(e.X, e.Y));
                var obj = GetObj_by_ScreenPoint(clickedPoint);
                bool isJunction = obj is NodeViewModel;
                if (obj != null)
                {
                    selectedObjs.ForEach(o => o.Selected = false);
                    selectedObjs.Clear();
                    obj.Selected = true;
                    selectedObjs.Add(obj);
                    if (GlobalObject.PropertyForm != null)
                        GlobalObject.PropertyForm.SetObjs(selectedObjs);
                    _OperaNode = null;
                    SetMapInvalidate();
                    mousePosition = new PointF(0, 0);
                }
                else
                {
                    //GlobalObject.LockSelect
                    selectedObjs.ForEach(o => o.Selected = false);
                    selectedObjs.Clear();
                    if (GlobalObject.PropertyForm != null)
                        GlobalObject.PropertyForm.SetObjs(selectedObjs);
                    _OperaNode = null;
                    SetMapInvalidate();
                }
                return;
            }
            if (/*叠加点选*/!isMouseMoved && _mouseState == MouseState.无 && e.Button == MouseButtons.Left && ModifierKeys == Keys.Control)
            {
                _isDragging = false;
                // 遍历所有点,找出最近的点
                PointF clickedPoint = new PointF(e.X, e.Y);  //ScreenToMap(new PointF(e.X, e.Y));
                var obj = GetObj_by_ScreenPoint(clickedPoint);
                bool isJunction = obj is NodeViewModel;
                if (obj != null)
                {
                    if (selectedObjs.Contains(obj))
                    {
                        obj.Selected = false;
                        selectedObjs.Remove(obj);
                        if (GlobalObject.PropertyForm != null)
                            GlobalObject.PropertyForm.SetObjs(selectedObjs);
                        SetMapInvalidate();
                        mousePosition = new PointF(0, 0);
                    }
                    else
                    {
                        obj.Selected = true;
                        selectedObjs.Add(obj);
                        if (GlobalObject.PropertyForm != null)
                            GlobalObject.PropertyForm.SetObjs(selectedObjs);
                        SetMapInvalidate();
                        mousePosition = new PointF(0, 0);
                    }
                }
                return;
            }
            if (e.Button == MouseButtons.Right)
            {
                if (_isRotating)
                {
                    _isRotating = false;
                    this.Cursor = _lastCursor;
                    if (recordView) MapObjectExtensions.AddCommand(mapOption, "Map", mapOption0, mapOption);
                    mousePosition = new PointF(0, 0);
                }
            }
        }
        #endregion
        #endregion 一、全局
@@ -1861,7 +1993,7 @@
        {
            if (_filePath == null) return;
            FileInfo fi = new FileInfo(_filePath);
            Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
            System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
            //System.Diagnostics.Process.Start("explorer.exe", fi.Directory.FullName);
        }
        private void EPA中打开ToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1869,7 +2001,7 @@
            if (_filePath == null) return;
            Process.Start(@"epanetH\Epanet2wH.exe", _filePath);
            System.Diagnostics.Process.Start(@"epanetH\Epanet2wH.exe", _filePath);
        }
        private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
@@ -1922,6 +2054,55 @@
        {
            _mouseState = MouseState.无;
            Cursor = Cursors.Default;
            if (_isPainting)
            {
                _select_junction1 = null;
                _isPainting = false;
                SetMapInvalidate();
            }
            else if (_isDragging)
            {
                _isDragging = false;
                SetMapInvalidate();
            }
            else if (_isPanning)
            {
                _isPanning = false;
                SetMapInvalidate();
            }
            else if (_isRotating)
            {
                Rotation = Rotation0;
                _isRotating = false;
                SetMapInvalidate();
            }
            else if (_isMovingObject)
            {
                _NewNet.Clear();
                _isMovingObject = false;
                SetMapInvalidate();
            }
            else if (_mouseState != MouseState.无)
            {
                _mouseState = MouseState.无;
                Cursor = Cursors.Default;
            }
            else if (_isInsertingObject)
            {
                _NewNet.Clear();
                _isInsertingObject = false;
                _OperaNode = null;
                SetMapInvalidate();
            }
            else
            {
                _Nodes.ForEach(o => ((NodeViewModel)o).Selected = false);
                _Links.ForEach(o => ((LinkViewModel)o).Selected = false);
                selectedObjs.Clear();
                SetMapInvalidate();
            }
        }
        public void toolStripButton_新建管线_Click(object sender, EventArgs e)
@@ -2073,7 +2254,7 @@
            }
            if (e.KeyCode == Keys.Delete)
            if (_IsEditMode && e.KeyCode == Keys.Delete)
            {
                DeleteChoosedObj();
            }
@@ -2085,29 +2266,29 @@
                SetMapInvalidate();
            }
            if (e.KeyCode == Keys.C && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.C && e.Modifiers == Keys.Control)
            {
                复制ToolStripMenuItem_Click(1, new EventArgs());
            }
            if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
            {
                _ClickStartPos = Cursor.Position;
                粘贴ToolStripMenuItem1_Click(1, new EventArgs());
            }
            if (e.KeyCode == Keys.D1 && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.D1 && e.Modifiers == Keys.Control)
            {
                南北对齐ToolStripMenuItem_Click(1, new EventArgs());
            }
            if (e.KeyCode == Keys.Oemtilde && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.Oemtilde && e.Modifiers == Keys.Control)
            {
                东西对齐ToolStripMenuItem_Click(1, new EventArgs());
            }
            if (e.KeyCode == Keys.D2 && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.D2 && e.Modifiers == Keys.Control)
            {
                竖直对齐ToolStripMenuItem_Click(1, new EventArgs());
            }
            if (e.KeyCode == Keys.D3 && e.Modifiers == Keys.Control)
            if (_IsEditMode && e.KeyCode == Keys.D3 && e.Modifiers == Keys.Control)
            {
                自动对齐ToolStripMenuItem_Click(1, new EventArgs());
            }
@@ -2117,7 +2298,7 @@
        private void MapViewer_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (ctrlPressed && e.KeyChar == 'Z' - 64)
            if (_IsEditMode && ctrlPressed && e.KeyChar == 'Z' - 64)
            {
                // 执行相应的操作
                buttonUndo_Click(sender, e);
@@ -2126,7 +2307,7 @@
                // 防止默认操作
                e.Handled = true;
            }
            if (ctrlPressed && e.KeyChar == 'Y' - 64)
            if (_IsEditMode && ctrlPressed && e.KeyChar == 'Y' - 64)
            {
                // 执行相应的操作
                buttonRedo_Click(sender, e);
@@ -2147,14 +2328,14 @@
        }
        private void MapViewer_PreKeyPress(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.Z)
            if (_IsEditMode && e.Control && e.KeyCode == Keys.Z)
            {
                ctrlPressed = true;
                // 防止默认操作
                e.IsInputKey = true;
            }
            if (e.Control && e.KeyCode == Keys.Y)
            if (_IsEditMode && e.Control && e.KeyCode == Keys.Y)
            {
                ctrlPressed = true;
                // 防止默认操作
@@ -2302,7 +2483,7 @@
        {
            _IsEditMode = !_IsEditMode;
            //toolStripComboBox_浏览模式.Text = isEditMode ? "编辑模式" : "浏览模式";
            LoadData(true);
            //LoadData(true);
        }
        private void 浏览模式ToolStripMenuItem_Click(object sender, EventArgs e)
@@ -2310,7 +2491,7 @@
            var obj = sender as ToolStripItem;
            _IsEditMode = obj.Text == "编辑模式";
            //toolStripComboBox_浏览模式.Text = isEditMode ? "编辑模式" : "浏览模式";
            LoadData(true);
            //LoadData(true);
        }
        #endregion
@@ -2538,11 +2719,155 @@
        }
        private void btn_初分配_Click(object sender, EventArgs e)
        {
            if (_Network == null) return;
            //btn_拓扑检查_Click(1,null);
            List<WaterEquivalentSettings> settings = new List<WaterEquivalentSettings>();
            settings.Add(new WaterEquivalentSettings()
            {
                waterEquivalents=new WaterEquivalentTemplate()
                {
                    ID="1",
                    Name="1",
                    WaterEquivalentCollection=new WaterEquivalentCollection()
                    {
                        new WaterEquivalent()
                        {
                            ID=1008,
                            MinRatedFlow=0.48f,
                            RatedFlow=0.72f,
                            Count=1,
                        },
                        //new WaterEquivalent()
                        //{
                        //    ID=1009,
                        //    MinRatedFlow=0.88f,
                        //    RatedFlow=0.96f,
                        //    Count=2,
                        //},
                        //new WaterEquivalent()
                        //{
                        //    ID=1010,
                        //    MinRatedFlow=1.08f,
                        //    RatedFlow=1.08f,
                        //    Count=3,
                        //}
                    }
                },
                Meters=new List<string>()
                {
                    //按以下规律生成数组到M10,"M1","M2"
                        "M0","M1","M2","M3","M4","M5","M6"
                },
            });
            //settings.Add(new WaterEquivalentSettings()
            //{
            //    waterEquivalents = new WaterEquivalentTemplate()
            //    {
            //        ID = "1",
            //        Name = "1",
            //        WaterEquivalentCollection = new WaterEquivalentCollection()
            //        {
            //            new WaterEquivalent()
            //            {
            //                ID=2008,
            //                MinRatedFlow=0.48f,
            //                RatedFlow=0.48f,
            //                Count=1,
            //            },
            //            new WaterEquivalent()
            //            {
            //                ID=2009,
            //                MinRatedFlow=0.12f,
            //                RatedFlow=0.12f,
            //                Count=5,
            //            },
            //            new WaterEquivalent()
            //            {
            //                ID=2010,
            //                MinRatedFlow=0.16f,
            //                RatedFlow=0.18f,
            //                Count=6,
            //            }
            //        }
            //    },
            //    Meters = new List<string>()
            //    {
            //        //按以下规律生成数组到M10,"M1","M2"
            //           "M31","M32","M33","M34","M35","M36","M37","M38","M39","M40","M41","M42","M43","M44","M45","M46","M47","M48","M49","M50","M51","M52","M53","M54","M55","M56","M57","M58","M59","M60","M61","M62","M63","M64","M65","M66","M67","M68","M69","M70","M71","M72","M73","M74","M75","M76","M77","M78","M79","M80"
            //    },
            //});
            var head=_Network.reservoirs.FirstOrDefault().Head;
            _Network.WaterDistribution(_Template.FullPath, GlobalPath.configPath + "config_waterDistri.wdb",settings,4, head);
        }
      public void btn_拓扑检查_Click(object sender, EventArgs e)
        {
            Dictionary<string,List<string>> result = _Template.network.CheckValidate();
            if (result.Count>0)
            {
                ResultForm resultForm = new ResultForm();
                ListBox listBox1 = resultForm.listBox1;
                listBox1.Items.AddRange(result.Keys.ToArray());
                listBox1.SelectedIndexChanged += (s, ee) =>
                {
                    //listBox2.Items.Clear();
                    if (listBox1.SelectedIndex >= 0)
                    {
                        var arr=result[listBox1.SelectedItem.ToString()].ToHashSet();
                        List<IBaseViewModel> Objs = new List<IBaseViewModel>();
                        Objs.AddRange(_Nodes.Select(n => (NodeViewModel)n));
                        Objs.AddRange(_Links.Select(l => (LinkViewModel)l));
                        var nodes = _Nodes.FindAll(o => arr.Contains(o.ID));
                        var links = _Links.FindAll(o => arr.Contains(o.ID));
                        //listBox2.Items.AddRange(result[listBox1.SelectedItem.ToString()].ToArray());
                        selectedObjs.ForEach(obj => obj.Selected = false);
                        selectedObjs.Clear();
                        nodes.ForEach(obj =>
                        {
                            obj.Selected = true;
                            selectedObjs.Add((NodeViewModel)obj);
                        });
                        links.ForEach(obj =>
                        {
                            obj.Selected = true;
                            selectedObjs.Add((LinkViewModel)obj);
                        });
                        if (GlobalObject.PropertyForm != null)
                            GlobalObject.PropertyForm.SetObjs(selectedObjs);
                        SetMapInvalidate();
                    }
                };
                resultForm.Text = "拓扑检查结果";
                resultForm.Show();
            }
            else
            {
                MessageBox.Show("拓扑检查通过");
            }
        }
        public void toolStripButton_计算_Click(object sender, EventArgs e)
        {
            //LoadData();
           if (_Template==null)
            {
                MessageBox.Show("请先打开文件");
                return;
            }
            _Network.Calc(_Template.FullPath, GlobalPath.configPath+ "config_calc.wdb");
        }
@@ -3204,6 +3529,59 @@
            }
        }
        /// <summary>
        /// 批量一键生成楼层模型
        /// </summary>
        public void BatchInsertNet(Template temp)
        {
            var nodes = _Nodes.Where(c => c.Elev > 0).Select(node => (NodeViewModel)node).ToList();
            _undoOldValue = new PointF3D(0, 0, 0);
            _OperaNode = temp.network.Nodes.Find(node => node.ID == temp.Node1) as NodeViewModel;
            //foreach (var item in nodes)
            if (nodes.Any())
            {
                for (var i = 0; i < nodes.Count(); i++)
                {
                    var net = temp.network.DeepCopy();
                    float dx, dy, dz;
                    var p1 = (PointF3D)_undoOldValue;
                    var p2 = nodes[i].Position3D;
                    var dd = temp.OffSet;
                    dx = p2.X - p1.X;
                    dy = p2.Y - p1.Y;
                    dz = p2.Z - p1.Z;
                    net.Nodes.ForEach(n => { ((NodeViewModel)n).Position3D = new PointF3D(n.X + dx, n.Y + dy, n.Elev + dz); });
                    var list = _Network.Add(net);
                    //var j = _Network.AddPipe(nodes[i], _OperaNode);
                    //j.Length = 0.0001f;
                    //list.Add(j);
                    _NewNet.Clear();
                    _Network.BuildRelation();
                    selectedObjs.ForEach(o => o.Selected = false);
                    selectedObjs.Clear();
                    //list.ForEach(m => m.Selected = true);
                    //selectedObjs.AddRange(list);
                    MapObjectExtensions.AddCommand(_Network, "Add", null, list);
                }
                _OperaNode = null;
                //_OperaNode = null;
                //_Network.Nodes.AddRange(net.Nodes);
                //_Network.Links.AddRange(net.Links);
                SetMapInvalidate();
            }
        }
        private void 以当前视角另存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_Template == null) return;
@@ -3336,7 +3714,7 @@
                if (net.StartPoint == null) return;
                string SID = net.StartPoint.ID;
                net.StartPoint=net.Nodes.Find(n => n.ID == SID);
                PointF minPoint = new PointF(net.StartPoint.X, net.StartPoint.Y);
                PointF3D minPoint = net.StartPoint.Position3D;// new PointF(net.StartPoint.X, net.StartPoint.Y);
                Point controlLocation = this.PointToScreen(new Point(0, 0));
                int offsetX = Cursor.Position.X - controlLocation.X;
                int offsetY = Cursor.Position.Y - controlLocation.Y;
@@ -3348,11 +3726,12 @@
                if (hoveredObjs.Count>0 && hoveredObjs[0] is NodeViewModel minNode) 
                {
                   
                    var basePoint = minNode.Position;
                    var basePoint = minNode.Position3D;
                    net.Nodes.ForEach(obj =>
                    {
                        obj.X = obj.X + basePoint.X - minPoint.X;
                        obj.Y = obj.Y + basePoint.Y - minPoint.Y;
                        obj.Elev = obj.Elev + basePoint.Z - minPoint.Z;
                    });
                    
                    selectedObjs.ForEach(o => o.Selected = false);
@@ -3360,7 +3739,7 @@
                    selectedObjs.AddRange(net.Nodes.Select(n => (NodeViewModel)n));
                    selectedObjs.AddRange(net.Links.ViewLinks);
                    var list = _Network.Add(net,null,false,minNode);
                    net.BuildRelation();
                    //list.Add(_Network.AddPipe(Snode, minNode));
                    MapObjectExtensions.AddCommand(_Network, "Add", null, list);
                    SetMapInvalidate();
@@ -3378,6 +3757,7 @@
                    selectedObjs.AddRange(net.Nodes.Select(n => (NodeViewModel)n));
                    selectedObjs.AddRange(net.Links.ViewLinks);
                    var list = _Network.Add(net);
                    net.BuildRelation();
                    MapObjectExtensions.AddCommand(_Network, "Add", null, list);
                    SetMapInvalidate();
                }
@@ -3531,7 +3911,7 @@
            {
                var backgroundImagePath = openFileDialog.FileName;
                Global.ClearFileReadOnly(_Template.BackGroundImg_FullPath);
                File.Copy(backgroundImagePath, _Template.BackGroundImg_FullPath, true);
                FileCopy.Copy(backgroundImagePath, _Template.BackGroundImg_FullPath, true);
                设置底图ToolStripMenuItem_Click(1, new EventArgs());
            }
        }
@@ -3589,13 +3969,13 @@
        {
            if (_filePath == null) return;
            FileInfo fi = new FileInfo(_filePath);
            Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
            System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
        }
        private void label_file_Click(object sender, EventArgs e)
        {
            if (_filePath == null) return;
            FileInfo fi = new FileInfo(_filePath);
            Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
            System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{_filePath}\"");
        }
        private void 设为立管点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
@@ -3769,7 +4149,7 @@
        bool _isShowDirection=false;
        private void 颜色分级管理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form_Colour form_Colour = new Form_Colour(_Template.Colours);
            Form_Colour form_Colour = new Form_Colour(_Template.Colours,_Template);
            form_Colour.Show(this);
        }
       
@@ -3780,18 +4160,30 @@
        private void cb_Link_Colour_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_Template == null) return;
            var type = cb_Link_Colour.SelectedItem==null?ColourType.管线流量:(ColourType)cb_Link_Colour.SelectedItem;
            mapOption.ColourLink = type;
            var type = cb_Link_Colour.SelectedItem == null ? ColourType.管线流量 : (ColourType)cb_Link_Colour.SelectedItem;
            var doubles = _Template.network.getMinMax(type);
            var colour = new Colour(type, null, type.ToString());
            List<ColourItem> colours = Colour.GetColourItems((float)doubles[0], (float)doubles[1], 5, Color.Gray, Color.Red);
            colour.Items = colours;
            LinkColour = colour;
            this.SetMapInvalidate();
        }
        private void cb_Node_Colour_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_Template == null) return;
            var type = cb_Node_Colour.SelectedItem==null?ColourType.节点自由压力:(ColourType)cb_Node_Colour.SelectedItem;
            mapOption.ColourNode = type;
            var type = cb_Node_Colour.SelectedItem == null ? ColourType.节点自由压力 : (ColourType)cb_Node_Colour.SelectedItem;
            var doubles = _Template.network.getMinMax(type);
            var colour = new Colour(type, null, type.ToString());
            List<ColourItem> colours = Colour.GetColourItems((float)doubles[0], (float)doubles[1], 5, Color.Gray, Color.Red);
            colour.Items = colours;
            NodeColour = colour;
            this.SetMapInvalidate();
        }
        private void label_ZZ_Click(object sender, EventArgs e)