Ejemplo n.º 1
0
    /// <summary>
    /// Imports a road graph.
    /// </summary>
    /// <param name="name">The name of the map used as prefix for the Verices and Edges file in the map folder.</param>
    /// <returns>A map with roads and intersections representing the road graph.</returns>
    public Map ReadMap(string name)
    {
        Map map = new Map(name);

        string[] vertLines = File.ReadAllLines($"../../../Maps/{name}Vertices.txt");
        string[] edgeLines = File.ReadAllLines($"../../../Maps/{name}Edges.txt");

        Dictionary <int, Vector3>       vertices = new Dictionary <int, Vector3>();                                                           // mapping of vertexID to position/vertex
        List <(Vector3, Vector3, bool)> edges    = new List <(Vector3, Vector3, bool)>();                                                     // an edge is represented by start and end position/vertex and a boolean for directedness.
        Dictionary <Vector3, List <(Vector3, Vector3, bool)> > adjactentEdges = new Dictionary <Vector3, List <(Vector3, Vector3, bool)> >(); //mapping of vertex to all its adjacent edges

        for (int i = 0; i < vertLines.Length; i++)                                                                                            // import vertices
        {
            string[] vars = vertLines[i].Split(',');
            Vector3  pos  = new Vector3(float.Parse(vars[1], CultureInfo.InvariantCulture), 0, float.Parse(vars[2], CultureInfo.InvariantCulture));
            vertices.Add(int.Parse(vars[0]), pos);
            adjactentEdges[pos] = new List <(Vector3, Vector3, bool)>();
        }

        for (int i = 0; i < edgeLines.Length; i++) //import edges and keep track of degrees so that intersections can be determined
        {
            string[] vars  = edgeLines[i].Split(',');
            Vector3  start = vertices[int.Parse(vars[1])];
            Vector3  end   = vertices[int.Parse(vars[2])];
            bool     dir   = vars.Length == 4 ? vars[3] == "1" : false; //if the map has directedness info then use it, otherwise everything is undirected
            adjactentEdges[start].Add((start, end, dir));
            adjactentEdges[end].Add((start, end, dir));
            edges.Add((start, end, dir));
        }

        foreach (Vector3 pos in vertices.Values) // make intersections for all the qualified vertices
        {
            List <(Vector3, Vector3, bool)> adjacents = adjactentEdges[pos];
            if (adjacents.Count == 1 || adjacents.Count > 2)                                              //if degree is 1 or larger than 2 a vertex is always an intersection.
            {
                Intersection i = new Intersection(pos, adjacents.Count(x => !x.Item3 || x.Item1 == pos)); //count amount of outgoing edges.
                map.intersections.Add(i);
                adjacents.RemoveAll(x => x.Item2 == pos);                                                 //remove adjacent edges where our new intersection is the end vertex.
            }
            else if (adjacents.Count == 2)                                                                // degree 2 vertices are intersections if the edges have different directedness, or are both outgoing or incoming.
            {
                if (adjacents[0].Item3 != adjacents[1].Item3 || adjacents.Count(x => x.Item1 == pos) == 2 || adjacents.Count(x => x.Item2 == pos) == 2)
                {
                    Intersection i = new Intersection(pos, adjacents.Count(x => !x.Item3 || x.Item1 == pos));
                    map.intersections.Add(i);
                    adjacents.RemoveAll(x => x.Item2 == pos);
                }
            }
        }

        foreach (Intersection intersection in map.intersections.FindAll(x => x.outgoing != null)) // make the roads for intersections that had outgoing edges.
        {
            List <(Vector3, Vector3, bool)> outEdges = adjactentEdges[intersection.position];

            for (int i = 0; i < outEdges.Count; i++)
            {
                Road road = new Road();
                road.directed = outEdges[i].Item3;

                road.start = intersection;
                road.roadPoints.Add(outEdges[i].Item1);
                road.roadPoints.Add(outEdges[i].Item2);

                Vector3 lastPoint = road.roadPoints[road.roadPoints.Count - 1]; //the last roadpoint found until now.
                while (!map.intersections.Exists(x => x.position == lastPoint)) //while there is no intersection equal to the last point in the road, we expand the road.
                {
                    (Vector3, Vector3, bool)next = adjactentEdges[lastPoint].Find(x => x.Item1 == lastPoint);
                    road.roadPoints.Add(next.Item2);
                    lastPoint = road.roadPoints[road.roadPoints.Count - 1];
                }

                road.end = map.intersections.Find(x => x.position == lastPoint);

                road.CalculateLength();

                road.start.outgoing.Add(road);
                if (!road.directed)
                {
                    road.end.outgoing.Add(road);
                }

                map.roads.Add(road);
            }
        }

        foreach (Road road in map.roads) //initialization of data used to keep track of road coverage of trajectory generation for the purpose of pruning the map.
        {
            for (int i = 0; i < road.roadPoints.Count; i++)
            {
                road.popularities.Add(0);
            }
        }

        map.Refresh();

        return(map);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Helpermethod to Prune a road perfectly based on its popularities.
    /// </summary>
    /// <param name="map">map we are pruning</param>
    /// <param name="road">road we would like to prune in it</param>
    /// <param name="unusedRoads">Roads that will be deleted by PruneRoad method.</param>
    /// <param name="newRoads">Roads that will be made by pruneRoad method.</param>
    public void PruneEdges(Map map, Road road, List <Road> unusedRoads, List <Road> newRoads)
    {
        int startChain = -1;                      //at which index does are start road end
        int tailChain  = road.popularities.Count; //at which index does our end road end

        while (startChain + 1 < road.popularities.Count && road.popularities[startChain + 1] > 0)
        {
            startChain++;
        }
        while (tailChain - 1 >= 0 && road.popularities[tailChain - 1] > 0)
        {
            tailChain--;
        }

        if (startChain == road.popularities.Count - 1)
        {
            return;         //road is completely traveled by trajectories
        }
        if (startChain < 1) // road has no start
        {
            //do nothing
        }
        else //road has a start
        {
            Road         startRoad    = new Road();
            Intersection startRoadEnd = new Intersection(road.roadPoints[road.roadPoints.Count - 1], road.directed ? 0 : 1);

            startRoad.start = road.start;
            for (int j = 0; j <= startChain; j++)
            {
                startRoad.roadPoints.Add(road.roadPoints[j]);
                startRoad.popularities.Add(road.popularities[j]);
            }
            startRoad.end = startRoadEnd;

            startRoad.directed  = road.directed;
            startRoad.traversed = road.traversed;
            startRoad.CalculateLength();


            startRoad.start.outgoing.Add(startRoad);
            if (!startRoad.directed)
            {
                startRoad.end.outgoing.Add(startRoad);
            }

            newRoads.Add(startRoad);
            map.intersections.Add(startRoadEnd);
        }

        if (tailChain > road.roadPoints.Count - 2) // road has no tail
        {
            //do nothing
        }
        else //road has a tail
        {
            Road         tailRoad      = new Road();
            Intersection tailRoadStart = new Intersection(road.roadPoints[tailChain], 1);

            tailRoad.start = tailRoadStart;
            for (int j = tailChain; j < road.roadPoints.Count; j++)
            {
                tailRoad.roadPoints.Add(road.roadPoints[j]);
                tailRoad.popularities.Add(road.popularities[j]);
            }
            tailRoad.end = road.end;

            tailRoad.directed  = road.directed;
            tailRoad.traversed = road.traversed;
            tailRoad.CalculateLength();

            tailRoad.start.outgoing.Add(tailRoad);
            if (!tailRoad.directed)
            {
                tailRoad.end.outgoing.Add(tailRoad);
            }

            newRoads.Add(tailRoad);
            map.intersections.Add(tailRoadStart);
        }

        unusedRoads.Add(road);
    }