Ejemplo n.º 1
0
        // 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);
        }
    /// <summary>
    /// 插入节点到Cluster内,并构建相关节点和边到图中
    /// </summary>
    private int InsertAbstractNodeInClusterLevel(HierarchicalMap map, Vector2Int concretePos)
    {
        AbstractNode abstractNode = map.GetAbstractNode(concretePos);

        //如果要插入的位置已经存在节点,则保存相关信息,以便之后删除时恢复
        if (abstractNode != null)
        {
            NodeBackup backup = new NodeBackup(abstractNode.Level, abstractNode.Edges.Values.ToList());

            if (m_backupDict.ContainsKey(abstractNode.Id))
            {
                Debug.LogError("已经存在一个NodeBackup,逻辑上出错了");
            }

            m_backupDict[abstractNode.Id] = backup;
            return(abstractNode.Id);
        }

        //把节点插入到Cluster内
        int abstractId = map.NodeCount();
        var cluster    = map.FindClusterForPosition(concretePos);
        var entrance   = cluster.AddEntrancePoint(abstractId, m_concreteMap.Get(concretePos));

        cluster.AddIntraEdgesData(entrance);
        //把节点插入到图中
        abstractNode = HPADemo.Instance.CreateAbstractNode(1, concretePos);
        abstractNode.Init(abstractId, 1, cluster.Id, concretePos);
        map.AddAbstractNode(abstractNode);
        map.AbstractGraph.AddNode(abstractNode);
        //把该节点相关的边插入到图中
        foreach (var otherEntrance in cluster.EntrancePoints)
        {
            if (cluster.IsConnected(abstractId, otherEntrance.AbstractId))
            {
                float        distance = cluster.Distance(abstractId, otherEntrance.AbstractId);
                AbstractEdge edge     = HPADemo.Instance.CreateEdge(concretePos, otherEntrance.ConcreteNode.Pos, 1, false);
                edge.Init(otherEntrance.AbstractId, distance, 1, false);
                map.AbstractGraph.AddEdge(abstractId, edge);

                edge = HPADemo.Instance.CreateEdge(otherEntrance.ConcreteNode.Pos, concretePos, 1, false);
                edge.Init(abstractId, distance, 1, false);
                map.AbstractGraph.AddEdge(otherEntrance.AbstractId, edge);
            }
        }

        return(abstractId);
    }