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); }
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); }