internal void AddVisGraphEdgesFromNodeCenterToNodeBorder(LgNodeInfo nodeInfo) {
     var vc = VisGraph.AddVertex(nodeInfo.Center);
     vc.IsTerminal = true; // we don't need to register this node in the tree
     foreach (var pt in nodeInfo.BoundaryOnLayer.PolylinePoints) {
         var vv = GetOrFindVisibilityVertex(pt.Point);
         var edge = VisibilityGraph.AddEdge(vc, vv);
         edge.IsPassable = () => EdgeIsPassable(edge);
     }
 }
        internal GraphmapsNode(Node node, LgNodeInfo lgNodeInfo, FrameworkElement frameworkElementOfNodeForLabelOfLabel,
            Func<Edge, GraphmapsEdge> funcFromDrawingEdgeToVEdge, Func<double> pathStrokeThicknessFunc)
        {
            PathStrokeThicknessFunc = pathStrokeThicknessFunc;
            LgNodeInfo = lgNodeInfo;
            Node = node;
            FrameworkElementOfNodeForLabel = frameworkElementOfNodeForLabelOfLabel;

            this.funcFromDrawingEdgeToVEdge = funcFromDrawingEdgeToVEdge;

            CreateNodeBoundaryPath();
            if (FrameworkElementOfNodeForLabel != null) {
                FrameworkElementOfNodeForLabel.Tag = this; //get a backpointer to the VNode 
                Common.PositionFrameworkElement(FrameworkElementOfNodeForLabel, node.GeometryNode.Center, 1);
                Panel.SetZIndex(FrameworkElementOfNodeForLabel, Panel.GetZIndex(BoundaryPath) + 1);
            }
            SetupSubgraphDrawing();
            Node.GeometryNode.BeforeLayoutChangeEvent += GeometryNodeBeforeLayoutChangeEvent;
            Node.Attr.VisualsChanged += (a, b) => Invalidate();         
           
        }
 void SelectNodeNoChangeEvent(LgNodeInfo nodeInfo, bool selected) {
     nodeInfo.Selected = selected;
     if (selected) {
         SelectedNodeInfos.Insert(nodeInfo);
     }
     else {
         SelectedNodeInfos.Remove(nodeInfo);
     }
 }
 void ScaleNode(LgNodeInfo nodeInfo, double xScale) {
     var p = nodeInfo.BoundingBox.Center;
     nodeInfo.GeometryNode.BoundaryCurve.Translate(-p);
     nodeInfo.GeometryNode.BoundaryCurve = nodeInfo.GeometryNode.BoundaryCurve.ScaleFromOrigin(xScale, xScale);
     nodeInfo.GeometryNode.BoundaryCurve.Translate(p);
     //nodeInfo.xScale *= xScale;
     //nodeInfo.GeometryNode.BoundaryCurve.ScaleFromOrigin()
 }
 void ZoomToNodeInfo(LgNodeInfo nodeInfo) {
     nodeInfo.Selected = true;
     _lgLayoutSettings.Interactor.SelectedNodeInfos.Insert(nodeInfo);
     var scale = Math.Max(CurrentScale, nodeInfo.LabelVisibleFromScale);
     var vp = new Rectangle(new Point(0, 0),
         new Point(_graphCanvas.RenderSize.Width, _graphCanvas.RenderSize.Height));
     SetTransformOnViewport(scale,nodeInfo.Center, vp);
     var drobject= nodeInfo.GeometryNode.UserData as DrawingObject;
     if (drobject != null) {
         IViewerObject ttt;
         if (_drawingObjectsToIViewerObjects.TryGetValue(drobject, out ttt)) {
             this.Invalidate(ttt);
         }
     }
 }
        void SelectUnselectNode(LgNodeInfo nodeInfo, bool selected) {
            nodeInfo.Selected = selected;
            if (selected)
                SelectedNodeInfos.Insert(nodeInfo);
            else
                SelectedNodeInfos.Remove(nodeInfo);

        }
 internal List<Point> GetPathOnSavedTrajectory(LgNodeInfo s, LgNodeInfo t, List<Point> trajectory,
     bool shrinkDistances) {
     if (trajectory == null || trajectory.Count < 2)
         return GetPath(s, t, true);
     
     var path = new List<Point> {trajectory[0]};
     for (int i = 0; i < trajectory.Count - 1; i++) {
         var p0 = trajectory[i];
         var p1 = trajectory[i + 1];
         var refinedPath = GetPointsOfVerticesOverlappingSegment(p0, p1);
         for (int j = 1; j < refinedPath.Count; j++)
             path.Add(refinedPath[j]);                
     }
     
     return path;
 }
 internal bool HasSavedTrajectory(LgNodeInfo s, LgNodeInfo t) {
     var t1 = new SymmetricTuple<LgNodeInfo>(s, t);
     return EdgeTrajectories.ContainsKey(t1);
 }
 static void SortPointByAngles(LgNodeInfo nodeInfo, Point[] polySplitArray) {
     var angles = new double[polySplitArray.Length];
     for (int i = 0; i < polySplitArray.Length; i++)
         angles[i] = Point.Angle(new Point(1, 0), polySplitArray[i] - nodeInfo.Center);
     Array.Sort(angles, polySplitArray);
 }
        private Set<VisibilityEdge> GetSegmentsOnPathsToInsertedNeighborsNotOnOldTrajectories(LgNodeInfo ni, Dictionary<SymmetricTuple<LgNodeInfo>, List<Point>> trajectories, LgPathRouter pathRouter)
        {
            var edges = new Set<VisibilityEdge>();
            var neighbors = GetAdjacentProcessed(ni);
            foreach (var neighb in neighbors) {
                var t1 = new SymmetricTuple<LgNodeInfo>(ni, neighb);
                List<Point> trajectory;
                if (trajectories.ContainsKey(t1)) trajectory = trajectories[t1];
                else continue;
                for (int i = 0; i < trajectory.Count - 1; i++)
                {
                    var p0 = trajectory[i];
                    var p1 = trajectory[i + 1];

                    var e = pathRouter.FindEdge(p0, p1);

                    Debug.Assert(e!=null, "VisibilityEdge on trajectory not found!");

                    if (!pathRouter.IsOnOldTrajectory(e))
                    {
                        edges.Insert(e);
                    }
                }
            }
            return edges;
        }
 void PerformNodeInsertion(LgNodeInfo node, Tuple<int, int> tile) {
     _nodeTileTable[tile]++;
     AddNodeToInserted(node);
     //orb.DrawDilated(node.BoundingBox);
 }
 void ReadLgNodeInfo(LgData lgData) {
     var nodeId = GetAttribute(GeometryToken.Id);
     var nodeInfo = new LgNodeInfo(nodeIdToNodes[nodeId]) {
         Rank = GetDoubleAttribute(GeometryToken.Rank),
         ZoomLevel = GetDoubleAttribute(GeometryToken.Zoomlevel),
         LabelVisibleFromScale = GetDoubleAttributeOrDefault(GeometryToken.LabelVisibleFromScale, 1.0),
         LabelWidthToHeightRatio = GetDoubleAttributeOrDefault(GeometryToken.LabelWidthToHeightRatio, 1.0),
         LabelOffset = TryGetPointAttribute(GeometryToken.LabelOffset)
     };
     lgData.SortedLgNodeInfos.Add(nodeInfo);
     lgData.GeometryNodesToLgNodeInfos[nodeIdToNodes[nodeId]] = nodeInfo;
     XmlRead();
 }
 Set<LgNodeInfo> GetAdjacentProcessed(LgNodeInfo ni) {
     var nodes = new Set<LgNodeInfo>(from edge in ni.GeometryNode.Edges
         let s = GeometryNodesToLgNodeInfos[edge.Source]
         let t = GeometryNodesToLgNodeInfos[edge.Target]
         select ni == s ? t : s
         into v
         where v.Processed
         select v);
     return nodes;
 }
        void AddNodeToInserted(LgNodeInfo ni) {
            _insertedNodes.Add(ni);

            var rect = new Rectangle(ni.Center, ni.Center);

            _insertedNodesTree.Add(rect, ni);
            _insertedNodeRectsTree.Add(rect, rect);
        }
        private void ShowDebugInsertedSegments(GridTraversal grid, int zoomLevel, LgNodeInfo nodeToAdd, IEnumerable<SymmetricSegment> newToAdd, IEnumerable<SymmetricSegment> allOnNewEdges)
        {
#if DEBUG && !SILVERLIGHT && !SHARPKIT && PREPARE_DEMO

            var edges = _pathRouter.GetAllEdgesVisibilityEdges();
            var ll = new List<DebugCurve>();

            foreach (var ni in _insertedNodes) {
                ll.Add(new DebugCurve(5, "green", ni.BoundaryCurve));
            }

            if (nodeToAdd != null) {
                var curve = _insertedNodes.Last().BoundaryCurve.Clone();
                curve.Translate(nodeToAdd.Center - _insertedNodes.Last().Center);
                ll.Add(new DebugCurve(5, "red", curve));
            }
            
            foreach (var e in edges)
            {
                ll.Add(new DebugCurve(new LineSegment(e.SourcePoint, e.TargetPoint)));
            }

            int n = zoomLevel;
            int maxNodes = MaxNodesPerTile(zoomLevel);

            for (int ix = 0; ix < n; ix++)
            {
                for (int iy = 0; iy < n; iy++)
                {
                    var tile = new Tuple<int, int>(ix, iy);
                    var r = grid.GetTileRect(ix, iy);
                    
                    if (_nodeTileTable.ContainsKey(tile)
                        && _nodeTileTable[tile] >= maxNodes)
                    {
                        ll.Add(new DebugCurve(5, "yellow", CurveFactory.CreateRectangle(r)));
                    }
                    else if (_segmentTileTable.ContainsKey(tile)
                             && _segmentTileTable[tile] >= MaxAmountRailsPerTile)
                    {
                        ll.Add(new DebugCurve(5, "orange", CurveFactory.CreateRectangle(r)));                    
                    }
                    else
                    {
                        ll.Add(new DebugCurve(5, "blue", CurveFactory.CreateRectangle(r)));
                    }
                }
            }

            if (allOnNewEdges != null) {
                foreach (var seg in allOnNewEdges) {
                    ll.Add(new DebugCurve(5, "yellow", new LineSegment(seg.A, seg.B)));
                }
            }

            if (newToAdd != null)
            {
                foreach (var seg in newToAdd)
                {
                    ll.Add(new DebugCurve(5, "red", new LineSegment(seg.A, seg.B)));
                }
            }

            LayoutAlgorithmSettings.ShowDebugCurves(ll.ToArray());

            PrintInsertedNodesLabels();
#endif
        }
 void WriteLgNodeInfo(LgNodeInfo lgNodeInfo) {
     WriteStartElement(GeometryToken.LgNodeInfo);
     WriteAttribute(GeometryToken.Id, nodeIds[lgNodeInfo.GeometryNode]);
     WriteAttribute(GeometryToken.Rank, lgNodeInfo.Rank );
     WriteAttribute(GeometryToken.Zoomlevel, lgNodeInfo.ZoomLevel);
     WriteAttribute(GeometryToken.LabelVisibleFromScale, lgNodeInfo.LabelVisibleFromScale);
     WriteAttribute(GeometryToken.LabelOffset, lgNodeInfo.LabelOffset);
     WriteAttribute(GeometryToken.LabelWidthToHeightRatio, lgNodeInfo.LabelWidthToHeightRatio);
     WriteEndElement();
 }
 internal Point[] GetPortVertices(LgNodeInfo node) {
     return node.BoundaryOnLayer.PolylinePoints.Select(pp => pp.Point).ToArray();
 }
 internal void ModifySkeletonWithNewBoundaryOnLayer(LgNodeInfo nodeInfo) {
     Dictionary<VisibilityEdge, VisibilityVertex> edgeSnapMap = GetEdgeSnapAtVertexMap(nodeInfo);            
     foreach (var t in edgeSnapMap) {
         VisibilityEdge edge = t.Key;
         VisibilityGraph.RemoveEdge(edge);
         var midleV = edgeSnapMap[edge];
         if (nodeInfo.Center != edge.SourcePoint)
             VisibilityGraph.AddEdge(edge.Source, midleV);
         else
             VisibilityGraph.AddEdge(midleV, edge.Target);
     }
 }
 internal List<Point> GetTrajectory(LgNodeInfo s, LgNodeInfo t) {
     List<Point> path;
     var tuple = new SymmetricTuple<LgNodeInfo>(s, t);
     EdgeTrajectories.TryGetValue(tuple, out path);
     return path;
 }
        Dictionary<VisibilityEdge, VisibilityVertex> GetEdgeSnapAtVertexMap(LgNodeInfo nodeInfo) {
            var ret = new Dictionary<VisibilityEdge, VisibilityVertex>();
            var center = nodeInfo.Center;
            RbTree<VisibilityVertex> nodeBoundaryRbTree =
                new RbTree<VisibilityVertex>((a, b) => CompareByAngleFromNodeCenter(a, b, center));
            foreach (var p in nodeInfo.BoundaryOnLayer)
                nodeBoundaryRbTree.Insert(_visGraph.AddVertex(p));

            var nodeInfoCenterV = VisGraph.FindVertex(center);
            if (nodeInfoCenterV == null) return ret;
            foreach (var e in nodeInfoCenterV.OutEdges)
                SnapToAfterBefore(e.Target, nodeBoundaryRbTree, center, ret, e);
            foreach (var e in nodeInfoCenterV.InEdges)
                SnapToAfterBefore(e.Source, nodeBoundaryRbTree, center, ret, e);
            return ret;
        }
 void AddNodeBoundaryToPointIndices(LgNodeInfo ni) {
     foreach (var polylinePoint in ni.BoundaryOnLayer.PolylinePoints)
         IndexAPoint(polylinePoint.Point);
 }
 internal List<Point> GetPath(LgNodeInfo s, LgNodeInfo t, bool shrinkDistances) {
     var vs = VisGraph.FindVertex(s.Center);
     Debug.Assert(vs!=null);
     var vt = VisGraph.FindVertex(t.Center);
     Debug.Assert(vt!=null);
     return GetPath(vs, vt, shrinkDistances);
 }
 bool GettingTooCloseToNode(LgNodeInfo lgNodeInfo, Point a, Point b) {            
     var center = lgNodeInfo.Center;
     if (a == center || b == center) return false;
     var closestPoint = Point.ClosestPointAtLineSegment(center, a, b);
     var where = Curve.PointRelativeToCurveLocation(closestPoint, lgNodeInfo.BoundaryOnLayer);
     return where == PointLocation.Inside;
     /*
     LayoutAlgorithmSettings.ShowDebugCurves(
       new Microsoft.Msagl.DebugHelpers.DebugCurve(100, 0.1, "blue", lgNodeInfo.BoundaryOnLayer),
       new DebugHelpers.DebugCurve(100, 0.1, "red", new LineSegment(a, b)));
   
     return true; // the intersection is not at the end of the [a,b]
      */
 }
 private Rectangle NodeDotRect(LgNodeInfo ni)
 {
     double w = NodeDotWidth;
     return new Rectangle(ni.Center - 0.5 * new Point(w, w), ni.Center + 0.5 * new Point(w, w));
 }
 internal void SetTrajectoryAndAddEdgesToUsed(LgNodeInfo s, LgNodeInfo t, List<Point> path) {
     var t1 = new SymmetricTuple<LgNodeInfo>(s, t);
     if (_edgeTrajectories.ContainsKey(t1)) return;
     _edgeTrajectories[t1] = path;
     PathRouter.MarkEdgesUsedAlongPath(path);
 }