private void RestoreNodeBackup(HierarchicalMap map, Id <AbstractNode> nodeId)
        {
            var abstractGraph = map.AbstractGraph;
            var nodeBackup    = nodeBackups[nodeId];
            var nodeInfo      = abstractGraph.GetNodeInfo(nodeId);

            nodeInfo.Level = nodeBackup.Level;
            abstractGraph.RemoveEdgesFromAndToNode(nodeId);
            abstractGraph.AddNode(nodeId, nodeInfo);
            foreach (var edge in nodeBackup.Edges)
            {
                var targetNodeId = edge.TargetNodeId;

                map.AddEdge(nodeId, targetNodeId, edge.Info.Cost,
                            edge.Info.Level, edge.Info.IsInterClusterEdge,
                            edge.Info.InnerLowerLevelPath != null ? new List <Id <AbstractNode> >(edge.Info.InnerLowerLevelPath) : null);

                edge.Info.InnerLowerLevelPath?.Reverse();

                map.AddEdge(targetNodeId, nodeId, edge.Info.Cost,
                            edge.Info.Level, edge.Info.IsInterClusterEdge, edge.Info.InnerLowerLevelPath);
            }

            nodeBackups.Remove(nodeId);
        }
示例#2
0
        public void RemoveAbstractNode(HierarchicalMap map, Id <AbstractNode> nodeId, int stal)
        {
            var abstractGraph = map.AbstractGraph;

            if (m_stalUsed[stal])
            {
                // The node was an existing entrance point in the graph. Restore it with
                // the information we kept when inserting
                var nodeInfo = abstractGraph.GetNodeInfo(nodeId);
                nodeInfo.Level = m_stalLevel[stal];
                abstractGraph.RemoveEdgesFromAndToNode(nodeId);
                abstractGraph.AddNode(nodeId, nodeInfo);
                foreach (var edge in m_stalEdges[stal])
                {
                    var targetNodeId = edge.TargetNodeId;

                    map.AddEdge(nodeId, targetNodeId, edge.Info.Cost,
                                edge.Info.Level, edge.Info.IsInterClusterEdge);
                    map.AddEdge(targetNodeId, nodeId, edge.Info.Cost,
                                edge.Info.Level, edge.Info.IsInterClusterEdge);
                }
            }
            else
            {
                // Just delete the node from the graph
                var currentNodeInfo = abstractGraph.GetNodeInfo(nodeId);
                var clusterId       = currentNodeInfo.ClusterId;
                var cluster         = map.Clusters[clusterId.IdValue];
                cluster.RemoveLastEntranceRecord();
                map.ConcreteNodeIdToAbstractNodeIdMap.Remove(currentNodeInfo.ConcreteNodeId);
                abstractGraph.RemoveEdgesFromAndToNode(nodeId);
                abstractGraph.RemoveLastNode();
            }
        }
        // insert a new node, such as start or target, to the abstract graph and
        // returns the id of the newly created node in the abstract graph
        // x and y are the positions where I want to put the node
        private Id <AbstractNode> InsertNodeIntoHierarchicalMap(HierarchicalMap map, Id <ConcreteNode> concreteNodeId, Position pos)
        {
            // If the node already existed (for instance, it was the an entrance point already
            // existing in the graph, we need to keep track of the previous status in order
            // to be able to restore it once we delete this STAL
            if (map.ConcreteNodeIdToAbstractNodeIdMap.ContainsKey(concreteNodeId))
            {
                var existingAbstractNodeId = map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId];
                var nodeBackup             = new NodeBackup(
                    map.AbstractGraph.GetNodeInfo(existingAbstractNodeId).Level,
                    map.GetNodeEdges(concreteNodeId));
                nodeBackups[existingAbstractNodeId] = nodeBackup;
                return(map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId]);
            }

            var cluster = map.FindClusterForPosition(pos);

            // create global entrance
            var abstractNodeId = Id <AbstractNode> .From(map.NrNodes);

            var entrance = cluster.AddEntrance(abstractNodeId, new Position(pos.X - cluster.Origin.X, pos.Y - cluster.Origin.Y));

            cluster.UpdatePathsForLocalEntrance(entrance);

            map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId] = abstractNodeId;

            var info = new AbstractNodeInfo(
                abstractNodeId,
                1,
                cluster.Id,
                pos,
                concreteNodeId);

            map.AbstractGraph.AddNode(abstractNodeId, info);

            foreach (var entrancePoint in cluster.EntrancePoints)
            {
                if (cluster.AreConnected(abstractNodeId, entrancePoint.AbstractNodeId))
                {
                    map.AddEdge(
                        entrancePoint.AbstractNodeId,
                        abstractNodeId,
                        cluster.GetDistance(entrancePoint.AbstractNodeId, abstractNodeId));
                    map.AddEdge(
                        abstractNodeId,
                        entrancePoint.AbstractNodeId,
                        cluster.GetDistance(abstractNodeId, entrancePoint.AbstractNodeId));
                }
            }

            return(abstractNodeId);
        }