Пример #1
0
        private static bool IsLineVisible(RawRectangleF coordinateBounds, LineProxy line, int zoomLevel)
        {
            if (line == null || line.Coordinates == null || line.Coordinates.Count < 2)
            {
                return(false);
            }
            if (line.BaseLine == null)
            {
                return(false);
            }
            if (!coordinateBounds.Overlaps(line.Bounds))
            {
                return(false);
            }
            if (line.BaseLine.KVLevel.VisibilityByZoom > zoomLevel)
            {
                return(false);
            }
            if (!line.BaseLine.KVLevel.ShowEnergized && (line.BaseLine.LineEnergizationState == line.BaseLine.KVLevel.Energized))
            {
                return(false);
            }
            if (!line.BaseLine.KVLevel.ShowUnknown && (line.BaseLine.LineEnergizationState == line.BaseLine.KVLevel.Unknown))
            {
                return(false);
            }
            if (!line.BaseLine.KVLevel.ShowDeEnergized && (line.BaseLine.LineEnergizationState == line.BaseLine.KVLevel.DeEnergized))
            {
                return(false);
            }
            if (!line.BaseLine.KVLevel.ShowPartiallyEnergized && (line.BaseLine.LineEnergizationState == line.BaseLine.KVLevel.PartiallyEnergized))
            {
                return(false);
            }
            if (line.BaseLine.KVLevel.VisibilityThreshold > 0f && line.BaseLine.KVLevel.VisibilityThreshold < line.BaseLine.LinePercentage)
            {
                return(false);
            }
            if (line.BaseLine.KVLevel.VisibilityThreshold < 0f && -line.BaseLine.KVLevel.VisibilityThreshold > line.BaseLine.LinePercentage)
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        private void OnSelectedItemsChanged(SelectionChangedEventArgs args)
        {
            //Logic - by default when items scroll out of view they are no longer selected.
            //this is because the panel is virtualised and and automatically unselected due
            //to the control thinking that the item is not longer part of the overall collection
            if (_isSelecting)
            {
                return;
            }
            try
            {
                _isSelecting = true;

                _selected.Edit(innerList =>
                {
                    var toAdd = args.AddedItems.OfType <LineProxy>().ToList();

                    //may need to track if last selected is off the page:
                    var isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);

                    //get the last item at then end of the list

                    if (!isShiftKeyDown)
                    {
                        //if mouse down, we need to prevent items being cleated

                        //add items to list
                        foreach (var lineProxy in toAdd)
                        {
                            if (innerList.Contains(lineProxy))
                            {
                                continue;
                            }
                            _lastSelected = lineProxy;
                            innerList.Add(lineProxy);
                        }
                    }

                    else
                    {
                        //if shift down we need to override selected and manually select our selves
                        var last             = _lastSelected.Index;
                        var allSelectedItems = _selector.SelectedItems.OfType <LineProxy>().ToArray();
                        var currentPage      = _selector.Items.OfType <LineProxy>().ToArray();

                        //1. Determine whether all selected items are on the current page [plus whether last is on the current page]
                        var allOnCurrentPage = allSelectedItems.Intersect(currentPage).ToArray();

                        var lastInONcurrentPage = currentPage.Contains(_lastSelected);
                        if (lastInONcurrentPage && allOnCurrentPage.Length == allSelectedItems.Length)
                        {
                            innerList.Clear();
                            innerList.AddRange(allSelectedItems);
                            return;
                        }

                        args.Handled    = true;
                        var maxOfRecent = toAdd.Max(lp => lp.Index);

                        int min;
                        int max;
                        if (last < maxOfRecent)
                        {
                            min = last;
                            max = maxOfRecent;
                        }
                        else
                        {
                            min = maxOfRecent;
                            max = last;
                        }

                        //maintain selection
                        _selector.SelectedItems.Clear();
                        var fromCurrentPage = _selector.Items.OfType <LineProxy>()
                                              .Where(lp => lp.Index >= min && lp.Index <= max)
                                              .ToArray();

                        var fromPrevious = _recentlyRemovedFromVisibleRange
                                           .Items.Where(lp => lp.Index >= min && lp.Index <= max)
                                           .ToArray();

                        _recentlyRemovedFromVisibleRange.Clear();

                        //maintain our record
                        innerList.Clear();
                        innerList.AddRange(fromCurrentPage);
                        foreach (var previous in fromPrevious)
                        {
                            if (!innerList.Contains(previous))
                            {
                                innerList.Add(previous);
                            }
                        }

                        //finally reload the actual selection:
                        foreach (var item in innerList)
                        {
                            _selector.SelectedItems.Add(item);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "There has been a problem with manual selection");
            }
            finally
            {
                _isSelecting = false;
            }
        }
Пример #3
0
        private void UpdateAndDrawFlowArrow(RenderTime time, LineProxy proxy, int zoomLevel, MM_DisplayParameter displayOptions, SharpDX.Direct2D1.Brush brush)
        {
            //Now, draw the line as appropriate
            if (proxy.Coordinates == null || proxy.Coordinates.Count == 0)
            {
                return;
            }

            // reset if bad
            if (proxy.FlowPositionPercentage > 1)
            {
                proxy.FlowPositionPercentage = 1;
            }
            if (proxy.FlowPositionPercentage < float.Epsilon)
            {
                proxy.FlowPositionPercentage = 0;
            }

            // reset if bad
            if (proxy.FlowVarPositionPercentage > 1)
            {
                proxy.FlowVarPositionPercentage = 1;
            }
            if (proxy.FlowVarPositionPercentage < float.Epsilon)
            {
                proxy.FlowVarPositionPercentage = 0;
            }

            var Line = proxy.BaseLine;

            // don't render dead lines flow arrows
            if (Line == null || Math.Abs(Line.MVAFlow) < 0.1 || (Line.NearBus != null && Line.NearBus.Dead) || (Line.FarBus != null && Line.FarBus.Dead))
            {
                return;
            }

            //Determine how large our arrow should be

            float baseSize         = proxy.BaseLine.KVLevel.MVASize;
            float threshold        = proxy.BaseLine.KVLevel.MVAThreshold / 100.0f;
            bool  flowKvVisible    = proxy.BaseLine.KVLevel.ShowMVA;
            float mvaSize          = Line.KVLevel.MVASize;
            float lineWidth        = displayOptions.Width;
            float flowIncrement    = 0;
            float flowVarIncrement = 0;
            float flowSize;

            bool isTie = Line is MM_Tie;


            if ((!MM_Repository.OverallDisplay.ShowLineFlows || !flowKvVisible) && !(isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible))
            {
                return;
            }
            //MM_Repository.OverallDisplay.
            // absolute vs % limit
            bool absoluteValueFlowSize = zoomLevel < MM_Repository.OverallDisplay.LineFlows;

            if (isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible)
            {
                // show enhanced size/color for AC Tie lines if TieFlowDirectionVisible == true
                if (MM_Repository.KVLevels.ContainsKey("Tie"))
                {
                    mvaSize = MM_Repository.KVLevels["Tie"].MVASize;
                }
                else if (MM_Repository.KVLevels.ContainsKey("DCTie"))
                {
                    mvaSize = MM_Repository.KVLevels["DCTie"].MVASize;
                }
                else
                {
                    mvaSize = 5;
                }
            }
            else if (Line.KVLevel.Name.Contains("Tie"))
            {
                isTie = true;
            }
            bool  moveForward = true;
            float zoomScale   = (float)zoomLevel / MM_Repository.OverallDisplay.LineFlows;

            bool varForward  = true;
            var  varFlowSize = Math.Min(50, lineWidth * baseSize);

            if (absoluteValueFlowSize)
            {
                if (Math.Abs(Line.MVAFlow) < float.Epsilon)
                {
                    flowSize = flowIncrement = 0;
                }
                else
                {
                    moveForward = Line.MVAFlowDirection == Line.ConnectedStations[1];
                    varForward  = Line.MVARFlowDirection == Line.ConnectedStations[1];
                    flowSize    = (zoomLevel / 20f) * mvaSize * Line.MVAFlow * 0.02f; // + 1.5f * lineWidth;
                    varFlowSize = (zoomLevel / 20f) * mvaSize * Line.MVAFlow * 0.04f; // + 1.5f * lineWidth;
                }
            }
            else
            {
                // relative size based on limit
                if (Line.NormalLimit == 0)
                {
                    flowSize = flowIncrement = 0;
                }
                else
                {
                    var percentLimit = Line.MVAFlow / Line.NormalLimit;
                    var percentVar   = Line.MVARFlow / Line.NormalLimit;

                    if (percentLimit < threshold)
                    {
                        return;
                    }

                    moveForward = Line.MVAFlowDirection == Line.ConnectedStations[1];
                    varForward  = Line.MVARFlowDirection == Line.ConnectedStations[1];
                    flowSize    = 10f * mvaSize * percentLimit * ((float)(MathUtil.Clamp(lineWidth, 1, 3) / 2f));
                    varFlowSize = 30f * mvaSize * percentVar * ((float)(MathUtil.Clamp(lineWidth, 1, 3) / 2f));
                }
            }
            flowSize    = MathUtil.Clamp(flowSize, 0, 100);
            varFlowSize = MathUtil.Clamp(varFlowSize, 0, 100);

            if (float.IsNaN(flowSize) || flowSize < 0)
            {
                flowSize    = flowIncrement = 0;
                varFlowSize = flowVarIncrement = 0;
            }
            else
            {
                flowIncrement    = MathUtil.Clamp(0.5f * zoomScale * flowSize, -20f, 20f) * (float)time.ElapsedTime.TotalSeconds;
                flowVarIncrement = MathUtil.Clamp(0.5f * zoomScale * varFlowSize, -20f, 20f) * (float)time.ElapsedTime.TotalSeconds;
            }

            // scale up arrow (but not speed) based on zoom


            if (flowSize < lineWidth + 0.25f || proxy.Length <= 0 ||
                (MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideExternalElements && !Line.IsInternal))
            {
                return;
            }

            // Move MVA flow arrow
            if (moveForward)
            {
                proxy.FlowPositionPercentage += flowIncrement / proxy.Length;
            }
            else
            {
                proxy.FlowPositionPercentage -= flowIncrement / proxy.Length;
            }

            if (proxy.FlowPositionPercentage < float.Epsilon)
            {
                proxy.FlowPositionPercentage = 1 - proxy.FlowPositionPercentage;
            }
            else
            {
                proxy.FlowPositionPercentage -= (float)Math.Floor(proxy.FlowPositionPercentage); // just keep the decimal
            }
            // Move Var Arrow
            if (varForward)
            {
                proxy.FlowVarPositionPercentage += flowVarIncrement / proxy.Length;
            }
            else
            {
                proxy.FlowVarPositionPercentage -= flowVarIncrement / proxy.Length;
            }

            if (proxy.FlowVarPositionPercentage < float.Epsilon)
            {
                proxy.FlowVarPositionPercentage = 1 - proxy.FlowVarPositionPercentage;
            }
            else
            {
                proxy.FlowVarPositionPercentage -= (float)Math.Floor(proxy.FlowVarPositionPercentage); // just keep the decimal
            }
            if (zoomLevel < MM_Repository.OverallDisplay.LineFlows)
            {
                proxy.FlowPositionPercentage    = 0.5f;
                proxy.FlowVarPositionPercentage = 0.5f;
            }

            SolidColorBrush borderBrush = null;

            if (isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible)
            {
                bool importing = (Line.Substation1.IsInternal && (Line.MVAFlowDirection == Line.Substation1)) ||
                                 (Line.Substation2.IsInternal && (Line.MVAFlowDirection == Line.Substation2));

                var color = importing ? MM_Repository.OverallDisplay.TieFlowImportColor : MM_Repository.OverallDisplay.TieFlowExportColor;
                if (proxy.BlackStartDim)
                {
                    color = MM_Repository.OverallDisplay.BlackstartDim(color);
                }

                borderBrush = Surface.Brushes.GetBrush(color);
            }

            // add border around flow arrow for tie

            //proxy.FlowPositionPercentage = 0;
            float      rotAngle = 0;
            RawVector2 ArrowTip = proxy.GetPosition(proxy.FlowPositionPercentage, out rotAngle);

            float      varrotAngle = 0;
            RawVector2 varArrowTip = proxy.GetPosition(proxy.FlowVarPositionPercentage, out varrotAngle);

            //var
            if (MM_Repository.OverallDisplay.VarFlows)
            {
                DrawArrow(null, brush, varArrowTip, varrotAngle, varFlowSize, varForward, 0.1f);
            }

            // mva
            DrawArrow(brush, borderBrush, ArrowTip, rotAngle, flowSize, moveForward, 0.25f);
        }
Пример #4
0
        /// <summary>
        /// Rebuild our collection of lines to render
        /// </summary>
        /// <param name="updateTime">Time since last update.</param>
        /// <remarks>include base.Update(renderTime); in overloads to preserve updating UpdateTime field.</remarks>
        public override void Update(RenderTime updateTime)
        {
            base.Update(updateTime);

            if (!Surface.IsDirty && _lastZoom == Surface.Coordinates.ZoomLevel)
            {
                return;
            }

            _lastZoom = Surface.Coordinates.ZoomLevel;

            //_lineRenderProxies.Clear();
            //_multiLines.Clear();

            var lines = MM_Repository.Lines.Values.OrderBy(l => l.KVLevel.Nominal);

            Dictionary <string, int> lineStationMap = null;
            //_multiLines = new Dictionary<string, MultiLineProxy>();
            bool updateMultiLine = (_multiLines.Count == 0 || lastLineCount != MM_Repository.Lines.Count);

            lastLineCount = MM_Repository.Lines.Count;
            if (updateMultiLine)
            {
                lineStationMap = new Dictionary <string, int>();
            }
            foreach (var line in lines)
            {
                // checks to determine if we want to render this line
                if (line.IsZBR && line.Length > 150) // skip zbr
                {
                    continue;
                }

                // skip ties
                // if (line.ElemType.Name == "Tie")
                //     continue;

                // validations passed, calculate render info
                LineProxy proxy;
                if (!_lineRenderProxies.TryGetValue(line.TEID, out proxy))
                {
                    proxy = new LineProxy
                    {
                        BaseLine    = line,
                        Coordinates = new List <RawVector2>(line.Coordinates.Count)
                    };
                    _lineRenderProxies.Add(line.TEID, proxy);
                }
                LineProxy.CalculateCoords(proxy, line, _lastZoom);
                proxy.BlackStartDim = proxy.BlackStartHidden = false;

                // calculate blackstart parameters
                if ((MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideNonOperatorElements || MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.DimNonOperatorElements) && (line.Operator == null || !line.Operator.Equals(MM_Repository.OverallDisplay.DisplayCompany)))
                {
                    if (MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideNonOperatorElements)
                    {
                        proxy.BlackStartHidden = true;
                    }
                    else
                    {
                        proxy.BlackStartDim = true;
                    }
                }
                else if ((MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideNonBlackstartElements || MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.DimNonBlackstartElements) && !line.IsBlackstart)
                {
                    if (MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideNonBlackstartElements)
                    {
                        proxy.BlackStartHidden = true;
                    }
                    else
                    {
                        proxy.BlackStartDim = true;
                    }
                }
                else if ((MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideExternalElements || MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.DimExternalElements) && !line.IsInternal)
                {
                    if (MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideExternalElements)
                    {
                        proxy.BlackStartHidden = true;
                    }
                    else
                    {
                        proxy.BlackStartDim = true;
                    }
                }


                // update multilines
                if (updateMultiLine)
                {
                    // fast multiline detection
                    int sub1Teid = line.Substation1.TEID;
                    int sub2Teid = line.Substation2.TEID;

                    if (sub2Teid < sub1Teid)
                    {
                        sub1Teid = line.Substation2.TEID;
                        sub2Teid = line.Substation1.TEID;
                    }


                    string subTEIDToken = String.Format("{0:0}_{1:0}", sub1Teid, sub2Teid);

                    int otherMultiTeid;
                    if (lineStationMap.TryGetValue(subTEIDToken, out otherMultiTeid))
                    {
                        // multiline!
                        MultiLineProxy multi;
                        if (!_multiLines.TryGetValue(subTEIDToken, out multi))
                        {
                            // doesn't exist, add both lines
                            multi = new MultiLineProxy();
                            multi.Lines.Add(_lineRenderProxies[otherMultiTeid]);
                            _multiLines.Add(subTEIDToken, multi);
                        }

                        if (multi.Lines.All(l => l.BaseLine != proxy.BaseLine))
                        {
                            multi.Lines.Add(proxy);
                        }
                    }
                    else
                    {
                        lineStationMap.Add(subTEIDToken, line.TEID);
                    }
                }
            }

            if (lineStationMap != null)
            {
                lineStationMap.Clear();
            }
            lineStationMap = null;
        }
Пример #5
0
 private void ClearAllSelections()
 {
     _selected.Clear();
     _recentlyRemovedFromVisibleRange.Clear();
     _lastSelected = null;
 }
        private void OnSelectedItemsChanged(SelectionChangedEventArgs args)
        {

            //Logic - by default when items scroll out of view they are no longer selected.
            //this is because the panel is virtualised and and automatically unselected due
            //to the control thinking that the item is not longer part of the overall collection
            if (_isSelecting) return;
            try
            {
                _isSelecting = true;

                _selected.Edit(innerList =>
                {
                    var toAdd = args.AddedItems.OfType<LineProxy>().ToList();

                    //may need to track if last selected is off the page:
                    var isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);

                    //get the last item at then end of the list

                    if (!isShiftKeyDown)
                    {
                        //if mouse down, we need to prevent items being cleated

                        //add items to list
                        foreach (var lineProxy in toAdd)
                        {
                            if (innerList.Contains(lineProxy)) continue;
                            _lastSelected = lineProxy;
                            innerList.Add(lineProxy);
                        }
                    }
                    
                    else
                    {
                        //if shift down we need to override selected and manually select our selves
                        var last = _lastSelected.Index;
                        var allSelectedItems = _selector.SelectedItems.OfType<LineProxy>().ToArray();
                        var currentPage = _selector.Items.OfType<LineProxy>().ToArray();

                        //1. Determine whether all selected items are on the current page [plus whether last is on the current page]
                        var allOnCurrentPage = allSelectedItems.Intersect(currentPage).ToArray();

                        var lastInONcurrentPage = currentPage.Contains(_lastSelected);
                        if (lastInONcurrentPage && allOnCurrentPage.Length == allSelectedItems.Length)
                        {
                            innerList.Clear();
                            innerList.AddRange(allSelectedItems);
                            return;
                        }

                        args.Handled = true;
                        var maxOfRecent = toAdd.Max(lp => lp.Index);

                        int min;
                        int max;
                        if (last < maxOfRecent)
                        {
                            min = last;
                            max = maxOfRecent;
                        }
                        else
                        {
                            min = maxOfRecent;
                            max = last;
                        }

                        //maintain selection
                        _selector.SelectedItems.Clear();
                        var fromCurrentPage = _selector.Items.OfType<LineProxy>()
                            .Where(lp => lp.Index >= min && lp.Index <= max)
                            .ToArray();

                        var fromPrevious = _recentlyRemovedFromVisibleRange
                            .Items.Where(lp => lp.Index >= min && lp.Index <= max)
                            .ToArray();

                        _recentlyRemovedFromVisibleRange.Clear();

                        //maintain our record
                        innerList.Clear();
                        innerList.AddRange(fromCurrentPage);
                        foreach (var previous in fromPrevious)
                        {
                            if (!innerList.Contains(previous))
                                innerList.Add(previous);
                        }

                        //finally reload the actual selection:
                        foreach (var item in innerList)
                        {
                            _selector.SelectedItems.Add(item);
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.Error(ex,"There has been a problem with manual selection");
            }
            finally
            {
                _isSelecting = false;
            }
        }
Пример #7
0
 private void ClearAllSelections()
 {
     _selected.Clear();
     _recentlyRemovedFromVisibleRange.Clear();
     _lastSelected = null;
 }
Пример #8
0
        /// <summary>
        /// Creats a <see cref="PathGeometry"/> from a collection of GPS <see cref="PointF"/>s. This object should be disposed.
        /// </summary>
        /// <param name="lngLats">GPS Coordinates.</param>
        /// <param name="closed">Close the geometry.</param>
        /// <param name="filled">Fill the geometry.</param>
        /// <returns>IDisposable Object</returns>
        public PathGeometry CreateRegionPathGeometry(IList <Vector2> xy, out RawRectangleF bounds, bool closed = true, bool filled = false, bool simplify = false, float compression = 0.1f, float scaleX = 1f, float scaleY = 1f)
        {
            PathGeometry geometry = new PathGeometry(Factory2D);
            int          pnts     = 0;

            Vector2 scaleVector = new Vector2(scaleX, scaleY);

            if (xy.Count > 0)
            {
                var point = xy[0];
                if (Math.Abs(scaleX - 1f) > float.Epsilon || Math.Abs(scaleY - 1f) > float.Epsilon)
                {
                    point *= scaleVector;
                }
                var prev = point;

                float minX = point.X;
                float minY = point.Y;
                float maxX = point.X;
                float maxY = point.Y;

                using (var sink = geometry.Open())
                {
                    sink.SetFillMode(SharpDX.Direct2D1.FillMode.Winding);
                    sink.BeginFigure(point, filled ? FigureBegin.Filled : FigureBegin.Hollow);
                    int count = xy.Count;

                    for (int i = 1; i < count; i++)
                    {
                        // compression
                        if (simplify && i != count - 1) // don't compress last point
                        {
                            // linear compression
                            var  next     = xy[i + 1];
                            bool isLinear = LineProxy.HitTestLineSegmentF(xy[i].X, xy[i].Y, prev.X, prev.Y, next.X, next.Y, compression);

                            // distance compression
                            float d2 = LineProxy.DistanceSquared(xy[i].X, xy[i].Y, prev.X, prev.Y);

                            if (isLinear || d2 < compression)
                            {
                                continue;
                            }
                        }

                        if (Math.Abs(scaleX - 1f) > float.Epsilon || Math.Abs(scaleY - 1f) > float.Epsilon)
                        {
                            point = xy[i] * scaleVector;
                        }
                        else
                        {
                            point = xy[i];
                        }

                        sink.AddLine(point);
                        if (point.X < minX)
                        {
                            minX = point.X;
                        }
                        if (point.X > maxX)
                        {
                            maxX = point.X;
                        }

                        if (point.Y < minY)
                        {
                            minY = point.Y;
                        }
                        if (point.Y > maxY)
                        {
                            maxY = point.Y;
                        }


                        prev = xy[i];
                    }
                    sink.EndFigure(closed ? FigureEnd.Closed : FigureEnd.Open);
                    sink.Close();
                }

                bounds = new RawRectangleF(minX, minY, maxX, maxY);
            }
            else
            {
                bounds = new RawRectangleF(0, 0, 0, 0);
            }

            return(geometry);
        }