Пример #1
0
        /// <summary>
        /// Operation to add two routes together where
        /// the second route is just put after the first route.
        /// </summary>
        public static Route operator +(Route A, Route B)
        {
            if (A == null)
            {
                return(B);
            }
            else if (B == null)
            {
                return(A);
            }
            else
            {
                Node[] nodes = new Node[A.NumOfNodes + B.NumOfNodes];
                A.Points.CopyTo(nodes, 0);
                B.Points.CopyTo(nodes, A.NumOfNodes);

                Route res = new Route(nodes, A.GetVehicle(0));
                res.Length = A.Length + B.length;
                res.Time   = A.Time + B.Time;

                Vehicle prev = res.GetVehicle(0);
                Vehicle cur;

                for (int i = 1; i < A.NumOfNodes; i++)
                {
                    cur = A.GetVehicle(i);

                    if (prev != cur)
                    {
                        res.SetVehicle(cur, i);
                    }

                    prev = cur;
                }
                for (int i = 0; i < B.NumOfNodes; i++)
                {
                    cur = B.GetVehicle(i);

                    if (prev != cur)
                    {
                        res.SetVehicle(cur, i + A.NumOfNodes);
                    }

                    prev = cur;
                }

                return(res);
            }
        }
Пример #2
0
        /// <summary>
        /// Returns the right pen for the vehicle at index i of the route.
        /// So if at index i the vehicle is Car, the carPen will be returned.
        /// </summary>
        private Pen GetPen(Route r, int i)
        {
            switch (r.GetVehicle(i))
            {
            case Vehicle.Foot:
                return(footPen);

            case Vehicle.Bicycle:
                return(bikePen);

            case Vehicle.Car:
                return(carPen);

            case Vehicle.Bus:
                return(busPen);

            default:
                return(otherPen);
            }
        }
Пример #3
0
        /// <summary>
        /// Operation to add two routes together where
        /// the second route is just put after the first route.
        /// </summary>
        public static Route operator +(Route A, Route B)
        {
            if (A == null)
                return B;
            else if (B == null)
                return A;
            else
            {
                Node[] nodes = new Node[A.NumOfNodes + B.NumOfNodes];
                A.Points.CopyTo(nodes, 0);
                B.Points.CopyTo(nodes, A.NumOfNodes);

                Route res = new Route(nodes, A.GetVehicle(0));
                res.Length = A.Length + B.length;
                res.Time = A.Time + B.Time;

                Vehicle prev = res.GetVehicle(0);
                Vehicle cur;

                for (int i = 1; i < A.NumOfNodes; i++)
                {
                    cur = A.GetVehicle(i);

                    if (prev != cur)
                        res.SetVehicle(cur, i);

                    prev = cur;
                }
                for (int i = 0; i < B.NumOfNodes; i++)
                {
                    cur = B.GetVehicle(i);

                    if (prev != cur)
                        res.SetVehicle(cur, i + A.NumOfNodes);

                    prev = cur;
                }

                return res;
            }
        }
Пример #4
0
        private void OnPaint(object o, PaintEventArgs pea)
        {
            Graphics gr = pea.Graphics;

            gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Point corner = CoordToPoint(bounds.XMin, bounds.YMax);

            // Checks what tiles should be drawn and if available, draws them.
            for (int x = corner.X - corner.X % bmpWidth; x < corner.X + bmpWidth + this.Width; x += 128)
            {
                for (int y = corner.Y - corner.Y % bmpWidth; y > corner.Y - bmpHeight - this.Height; y -= 128)
                {
                    if (tileIndexes[tileIndex].ContainsKey(x) && tileIndexes[tileIndex][x].ContainsKey(y))
                    {
                        int index = tileIndexes[tileIndex][x][y];
                        gr.DrawImage(tiles[tileIndex][index], -corner.X + x, corner.Y - y - bmpHeight, bmpWidth, bmpHeight);
                    }
                    else
                    {
                        // Update becaues tile is missing.
                        if (updateThread.ThreadState == ThreadState.Stopped)
                        {
                            this.DoUpdate();
                        }
                    }
                }
            }


            if (streetSelection != null)
            {
                foreach (Curve c in streetSelection)
                {
                    Node  n   = graph.GetNode(c[0]);
                    Point cur = CoordToPoint(n.Longitude, n.Latitude);
                    cur = new Point(cur.X - corner.X, -cur.Y + corner.Y);
                    List <Point> points = new List <Point>();
                    points.Add(cur);

                    for (int i = 1; i < c.AmountOfNodes; i++)
                    {
                        n   = graph.GetNode(c[i]);
                        cur = CoordToPoint(n.Longitude, n.Latitude);
                        cur = new Point(cur.X - corner.X, -cur.Y + corner.Y);
                        //gr.DrawLine(otherPen, prev, cur);
                        points.Add(cur);
                    }

                    gr.DrawLines(otherPen, points.ToArray());
                }
            }


            foreach (MapIcon icon in icons)
            {
                icon.DrawIcon(gr);
            }


            //drawing the route
            if (route != null)
            {
                List <Point> points = new List <Point>();
                List <int>   changeVehiclePoints = new List <int>();

                int num = route.NumOfNodes;
                int x, y;


                for (int i = 0; i < num - 1; i++)
                {
                    Point pos = CoordToPoint(route[i].Longitude, route[i].Latitude);
                    x = pos.X - corner.X;
                    y = corner.Y - pos.Y;

                    points.Add(new Point(x, y));

                    if (route.GetVehicle(i) != route.GetVehicle(i + 1))
                    {
                        pos = CoordToPoint(route[i + 1].Longitude, route[i + 1].Latitude);
                        points.Add(new Point(pos.X - corner.X, corner.Y - pos.Y));

                        gr.DrawLines(GetPen(route, i), points.ToArray());

                        changeVehiclePoints.Add(i);

                        points = new List <Point>();
                    }
                }

                Point p = CoordToPoint(route[num - 1].Longitude, route[num - 1].Latitude);

                points.Add(new Point(p.X - corner.X, corner.Y - p.Y));
                if (points.Count > 1)
                {
                    gr.DrawLines(GetPen(route, num - 1), points.ToArray());
                }


                foreach (int index in changeVehiclePoints)
                {
                    p = CoordToPoint(route[index + 1].Longitude, route[index + 1].Latitude);
                    Point changePoint = new Point(p.X - corner.X, corner.Y - p.Y);
                    DrawChangeVehicleIcon(gr, changePoint, route.GetVehicle(index + 1));
                }
            }


            // Black borders of the mapDisplay.
            gr.DrawLine(Pens.Black, 0, 0, this.Width - 1, 0);
            gr.DrawLine(Pens.Black, 0, 0, 0, this.Height - 1);
            gr.DrawLine(Pens.Black, this.Width - 1, 0, this.Width - 1, this.Height - 1);
            gr.DrawLine(Pens.Black, 0, this.Height - 1, this.Width - 1, this.Height - 1);
        }
Пример #5
0
        /// <summary>
        /// Dijkstra in graph gr, from source to destination, using vehicle v.
        /// </summary>
        /// <param name="source"> the startpoint </param>
        /// <param name="destination"> the destination </param>
        /// <param name="v"> vehicle that is used </param>
        /// <returns></returns>
        public Route Dijkstra(long from, long to, Vehicle[] vehicles, RouteMode mode, bool useBus)
        {
            Route result = null;

            if (from == 0 || to == 0 || graph == null)
                return result;

            Node source = graph.GetNode(from);
            Node destination = graph.GetNode(to);

            //all nodes that are completely solved
            SortedList<long, Node> solved = new SortedList<long, Node>();

            //nodes that are encountered but not completely solved
            SortedList<double, Node> unsolved = new SortedList<double, Node>();

            RBTree<Node> prevs = new RBTree<Node>();
            RBTree<double> times = new RBTree<double>();
            RBTree<double> distances = new RBTree<double>();
            RBTree<Vehicle> vehicleUse = new RBTree<Vehicle>();
            ListTree<Vehicle> forbiddenVehicles = new ListTree<Vehicle>();
            List<Edge> abstractBusses = graph.GetAbstractBusEdges();

            Node current = source;
            bool found = false;

            //if there's no new current node it means the algorithm should stop
            while (current != null)
            {
                //if we encounter the destination it means we found the shortest route so we break
                if (current == destination)
                {
                    found = true;
                    break;
                }

                List<Edge> edges = new List<Edge>(graph.GetEdgesFromNode(current.ID));
                foreach (Edge busEdge in abstractBusses)
                {
                    if (busEdge.End == current.ID || busEdge.Start == current.ID)
                        edges.Add(busEdge);
                }

                Node prev = prevs.Get(current.ID);
                if (prev != null)
                {
                    foreach (Vehicle vehicle in forbiddenVehicles.Get(prev.ID))
                    {
                        forbiddenVehicles.Insert(current.ID, vehicle);
                    }
                }

                foreach (Edge e in edges)
                {
                    if (IsAllowed(e, vehicles, useBus))
                    {
                        Node start = graph.GetNode(e.Start);
                        Node end = graph.GetNode(e.End);
                        double distance = double.PositiveInfinity;
                        double time = double.PositiveInfinity;
                        Vehicle v = vehicles[0];

                        if (e.Type != CurveType.AbstractBusRoute)
                        {
                            if (e.Type != CurveType.Bus)
                            {
                                double speed = 0;
                                foreach (Vehicle vehicle in vehicles)
                                {
                                    if (!forbiddenVehicles.Get(current.ID).Contains(vehicle))
                                    {
                                        double vSpeed = GetSpeed(vehicle, e);
                                        if (vSpeed > speed && IsAllowed(e, vehicle, useBus))
                                        {
                                            speed = vSpeed;
                                            v = vehicle;
                                        }
                                    }
                                }

                                distance = NodeCalcExtensions.Distance(start, end);
                                time = distance / speed;
                            }
                            else if (e.Route != null)
                            {
                                // Take busroute if better
                                if (mode == RouteMode.Fastest && time > e.Route.Time || mode == RouteMode.Shortest && distance > e.Route.Length)
                                {
                                    distance = e.Route.Length;
                                    time = e.Route.Time;
                                    v = Vehicle.Foot;

                                    foreach (Vehicle vehicle in vehicles)
                                        if (vehicle != Vehicle.Foot)
                                            forbiddenVehicles.Insert(current.ID, vehicle);
                                }
                            }
                        }
                        else
                        {
                            Node n1 = null, n2 = null;
                            if (start.Longitude != 0 || start.Latitude != 0)
                                n1 = graph.GetNodeByPos(start.Longitude, start.Latitude, Vehicle.Bus);
                            if (end.Longitude != 0 || end.Latitude != 0)
                                n2 = graph.GetNodeByPos(end.Longitude, end.Latitude, Vehicle.Bus);

                            if (n1 != default(Node) && n2 != default(Node))
                            {
                                Curve curve = new Curve(new long[] { start.ID, end.ID }, e.Name);

                                Route r = this.Dijkstra(n1.ID, n2.ID, new Vehicle[] { Vehicle.Bus }, RouteMode.Fastest, false);
                                r = new Route(new Node[] { start }, Vehicle.Bus) + r + new Route(new Node[] { end }, Vehicle.Bus);

                                curve.Type = CurveType.Bus;
                                curve.Route = r;

                                // We calculate with 60 seconds of switch over to the bus.
                                r.Time += 60;

                                graph.AddWay(start.ID, curve);
                                graph.AddWay(end.ID, curve);

                                e.Route = r;
                                e.Type = CurveType.Bus;

                                // Take busroute if better
                                if (mode == RouteMode.Fastest && time > e.Route.Time || mode == RouteMode.Shortest && distance > e.Route.Length)
                                {
                                    distance = e.Route.Length;
                                    time = e.Route.Time;
                                    v = Vehicle.Foot;

                                    foreach (Vehicle vehicle in vehicles)
                                        if (vehicle != Vehicle.Foot)
                                            forbiddenVehicles.Insert(current.ID, vehicle);
                                }
                            }

                            graph.RemoveAbstractBus(e);
                            abstractBusses.Remove(e);
                        }

                        time += times.Get(current.ID);
                        double trueDist = distances.Get(current.ID) + distance;

                        if (!solved.ContainsValue(end) && current != end)
                        {
                            if (end.Latitude != 0 && end.Longitude != 0)
                            {
                                if (times.Get(end.ID) == 0 || distances.Get(end.ID) == 0)
                                {
                                    times.Insert(end.ID, double.PositiveInfinity);
                                    distances.Insert(end.ID, double.PositiveInfinity);
                                    vehicleUse.Insert(end.ID, v);
                                }

                                if ((mode == RouteMode.Fastest &&
                                    times.Get(end.ID) > time) ||
                                    (mode == RouteMode.Shortest &&
                                    distances.Get(end.ID) > trueDist))
                                {
                                    times.GetNode(end.ID).Content = time;
                                    distances.GetNode(end.ID).Content = trueDist;
                                    vehicleUse.GetNode(end.ID).Content = v;

                                    if (prevs.GetNode(end.ID).Content == null)
                                        prevs.Insert(end.ID, current);
                                    else
                                        prevs.GetNode(end.ID).Content = current;

                                    if (!unsolved.ContainsValue(end))
                                    {
                                        if (mode == RouteMode.Fastest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(times.Get(end.ID)))
                                            {
                                                times.GetNode(end.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(times.Get(end.ID), end);

                                        }
                                        else if (mode == RouteMode.Shortest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(distances.Get(end.ID)))
                                            {
                                                distances.GetNode(end.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(distances.Get(end.ID), end);
                                        }

                                        if (prevs.GetNode(current.ID).Content != null &&
                                            vehicleUse.Get(prevs.GetNode(current.ID).Content.ID) == Vehicle.Car)
                                        {
                                            if (v == Vehicle.Foot)
                                            {
                                                forbiddenVehicles.Insert(end.ID, Vehicle.Car);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else if (!solved.ContainsValue(start) && current != start)
                        {
                            if (start.Latitude != 0 && start.Longitude != 0)
                            {
                                if (times.Get(start.ID) == 0 || distances.Get(start.ID) == 0)
                                {
                                    times.Insert(start.ID, double.PositiveInfinity);
                                    distances.Insert(start.ID, double.PositiveInfinity);
                                    vehicleUse.Insert(start.ID, v);
                                }

                                if ((mode == RouteMode.Fastest &&
                                    times.Get(start.ID) > time) ||
                                    (mode == RouteMode.Shortest &&
                                    distances.Get(start.ID) > trueDist))
                                {
                                    times.GetNode(start.ID).Content = time;
                                    distances.GetNode(start.ID).Content = trueDist;
                                    vehicleUse.GetNode(start.ID).Content = v;

                                    if (prevs.GetNode(start.ID).Content == null)
                                        prevs.Insert(start.ID, current);
                                    else
                                        prevs.GetNode(start.ID).Content = current;

                                    if (!unsolved.ContainsValue(start))
                                    {
                                        if (mode == RouteMode.Fastest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(times.Get(start.ID)))
                                            {
                                                times.GetNode(start.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(times.Get(start.ID), start);
                                        }
                                        else if (mode == RouteMode.Shortest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(distances.Get(start.ID)))
                                            {
                                                distances.GetNode(start.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(distances.Get(start.ID), start);
                                        }
                                    }

                                    if (prevs.GetNode(current.ID).Content != null &&
                                        vehicleUse.Get(prevs.GetNode(current.ID).Content.ID) == Vehicle.Car)
                                    {
                                        if (v == Vehicle.Foot)
                                        {
                                            forbiddenVehicles.Insert(start.ID, Vehicle.Car);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                //dit zou niet voor moeten komen maar toch gebeurt het...
                if (!solved.ContainsKey(current.ID))
                    solved.Add(current.ID, current);

                if (unsolved.Count > 0)
                {
                    current = unsolved.Values[0];
                    unsolved.RemoveAt(0);
                }
                else
                {
                    current = null;
                }
            }

            if (found)
            {
                List<Node> nodes = new List<Node>();
                List<long> extras = graph.GetExtras();
                Node n = destination;

                List<long> busStartStop = new List<long>();

                do
                {
                    bool foundRoute = false;

                    if (extras.Contains(n.ID))
                    {
                        // Change straigt buslines in for the actual route.
                        foreach (Edge e in graph.GetEdgesFromNode(n.ID))
                        {
                            if (prevs.Get(n.ID) != null && e.Route != null)
                            {
                                if (n.ID == e.Start &&
                                    prevs.Get(n.ID).ID == e.End)
                                {
                                    Node[] busNodes = e.Route.Points;

                                    if (busNodes[0].ID == e.Start)
                                        Array.Reverse(busNodes);

                                    busStartStop.Add(busNodes[busNodes.Length - 1].ID);
                                    busStartStop.Add(busNodes[0].ID);
                                    nodes.InsertRange(0, busNodes);

                                    n = prevs.Get(n.ID);

                                    foundRoute = true;
                                    break;
                                }
                                else if (n.ID == e.End &&
                                         prevs.Get(n.ID).ID == e.Start)
                                {

                                    Node[] busNodes = e.Route.Points;

                                    if (busNodes[0].ID == e.End)
                                        Array.Reverse(busNodes);

                                    busStartStop.Add(busNodes[busNodes.Length - 1].ID);
                                    busStartStop.Add(busNodes[0].ID);
                                    nodes.InsertRange(0, busNodes);

                                    n = prevs.Get(n.ID);

                                    foundRoute = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (!foundRoute)
                    {
                        nodes.Insert(0, n);
                        n = prevs.Get(n.ID);
                    }

                } while (n != null);

                result = new Route(nodes.ToArray(), vehicles[0]);
                result.Time = times.Get(destination.ID);
                result.Length = distances.Get(destination.ID);

                // Set bus as vehicle
                if (busStartStop.Count > 0)
                {
                    int i = busStartStop.Count - 1;
                    Node[] routePoints = result.Points;

                    for (int j = 0; j < routePoints.Length; j++)
                    {
                        if (routePoints[j].ID == busStartStop[i])
                        {
                            if (i % 2 == 1)
                            {
                                result.SetVehicle(Vehicle.Bus, j);
                                i--;
                            }
                            else
                            {
                                result.SetVehicle(Vehicle.Foot, j);
                                i--;
                            }
                        }

                        if (i < 0)
                            break;
                    }
                }

                Vehicle cur = result.GetVehicle(0), prev;
                for (int i = 2; i < result.NumOfNodes; i++)
                {
                    if (result.GetVehicle(i) != Vehicle.Bus)
                    {
                        prev = vehicleUse.Get(result[i].ID);

                        if (prev != cur && i > 1)
                            result.SetVehicle(prev, i - 1);

                        cur = prev;
                    }
                }

            }
            else
            {
                result = new Route(new Node[] { source }, vehicles[0]);
                result.Time = double.PositiveInfinity;
                result.Length = double.PositiveInfinity;
            }

            return result;
        }
Пример #6
0
 /// <summary>
 /// Returns the right pen for the vehicle at index i of the route.
 /// So if at index i the vehicle is Car, the carPen will be returned.
 /// </summary>
 private Pen GetPen(Route r, int i)
 {
     switch (r.GetVehicle(i))
     {
         case Vehicle.Foot:
             return footPen;
         case Vehicle.Bicycle:
             return bikePen;
         case Vehicle.Car:
             return carPen;
         case Vehicle.Bus:
             return busPen;
         default:
             return otherPen;
     }
 }
Пример #7
0
        /// <summary>
        /// Dijkstra in graph gr, from source to destination, using vehicle v.
        /// </summary>
        /// <param name="source"> the startpoint </param>
        /// <param name="destination"> the destination </param>
        /// <param name="v"> vehicle that is used </param>
        /// <returns></returns>
        public Route Dijkstra(long from, long to, Vehicle[] vehicles, RouteMode mode, bool useBus)
        {
            Route result = null;

            if (from == 0 || to == 0 || graph == null)
            {
                return(result);
            }


            Node source      = graph.GetNode(from);
            Node destination = graph.GetNode(to);

            //all nodes that are completely solved
            SortedList <long, Node> solved = new SortedList <long, Node>();


            //nodes that are encountered but not completely solved
            SortedList <double, Node> unsolved = new SortedList <double, Node>();

            RBTree <Node>      prevs             = new RBTree <Node>();
            RBTree <double>    times             = new RBTree <double>();
            RBTree <double>    distances         = new RBTree <double>();
            RBTree <Vehicle>   vehicleUse        = new RBTree <Vehicle>();
            ListTree <Vehicle> forbiddenVehicles = new ListTree <Vehicle>();
            List <Edge>        abstractBusses    = graph.GetAbstractBusEdges();

            Node current = source;
            bool found   = false;

            //if there's no new current node it means the algorithm should stop
            while (current != null)
            {
                //if we encounter the destination it means we found the shortest route so we break
                if (current == destination)
                {
                    found = true;
                    break;
                }


                List <Edge> edges = new List <Edge>(graph.GetEdgesFromNode(current.ID));
                foreach (Edge busEdge in abstractBusses)
                {
                    if (busEdge.End == current.ID || busEdge.Start == current.ID)
                    {
                        edges.Add(busEdge);
                    }
                }


                Node prev = prevs.Get(current.ID);
                if (prev != null)
                {
                    foreach (Vehicle vehicle in forbiddenVehicles.Get(prev.ID))
                    {
                        forbiddenVehicles.Insert(current.ID, vehicle);
                    }
                }

                foreach (Edge e in edges)
                {
                    if (IsAllowed(e, vehicles, useBus))
                    {
                        Node    start    = graph.GetNode(e.Start);
                        Node    end      = graph.GetNode(e.End);
                        double  distance = double.PositiveInfinity;
                        double  time     = double.PositiveInfinity;
                        Vehicle v        = vehicles[0];


                        if (e.Type != CurveType.AbstractBusRoute)
                        {
                            if (e.Type != CurveType.Bus)
                            {
                                double speed = 0;
                                foreach (Vehicle vehicle in vehicles)
                                {
                                    if (!forbiddenVehicles.Get(current.ID).Contains(vehicle))
                                    {
                                        double vSpeed = GetSpeed(vehicle, e);
                                        if (vSpeed > speed && IsAllowed(e, vehicle, useBus))
                                        {
                                            speed = vSpeed;
                                            v     = vehicle;
                                        }
                                    }
                                }

                                distance = NodeCalcExtensions.Distance(start, end);
                                time     = distance / speed;
                            }
                            else if (e.Route != null)
                            {
                                // Take busroute if better
                                if (mode == RouteMode.Fastest && time > e.Route.Time || mode == RouteMode.Shortest && distance > e.Route.Length)
                                {
                                    distance = e.Route.Length;
                                    time     = e.Route.Time;
                                    v        = Vehicle.Foot;

                                    foreach (Vehicle vehicle in vehicles)
                                    {
                                        if (vehicle != Vehicle.Foot)
                                        {
                                            forbiddenVehicles.Insert(current.ID, vehicle);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            Node n1 = null, n2 = null;
                            if (start.Longitude != 0 || start.Latitude != 0)
                            {
                                n1 = graph.GetNodeByPos(start.Longitude, start.Latitude, Vehicle.Bus);
                            }
                            if (end.Longitude != 0 || end.Latitude != 0)
                            {
                                n2 = graph.GetNodeByPos(end.Longitude, end.Latitude, Vehicle.Bus);
                            }

                            if (n1 != default(Node) && n2 != default(Node))
                            {
                                Curve curve = new Curve(new long[] { start.ID, end.ID }, e.Name);

                                Route r = this.Dijkstra(n1.ID, n2.ID, new Vehicle[] { Vehicle.Bus }, RouteMode.Fastest, false);
                                r = new Route(new Node[] { start }, Vehicle.Bus) + r + new Route(new Node[] { end }, Vehicle.Bus);

                                curve.Type  = CurveType.Bus;
                                curve.Route = r;

                                // We calculate with 60 seconds of switch over to the bus.
                                r.Time += 60;

                                graph.AddWay(start.ID, curve);
                                graph.AddWay(end.ID, curve);

                                e.Route = r;
                                e.Type  = CurveType.Bus;

                                // Take busroute if better
                                if (mode == RouteMode.Fastest && time > e.Route.Time || mode == RouteMode.Shortest && distance > e.Route.Length)
                                {
                                    distance = e.Route.Length;
                                    time     = e.Route.Time;
                                    v        = Vehicle.Foot;

                                    foreach (Vehicle vehicle in vehicles)
                                    {
                                        if (vehicle != Vehicle.Foot)
                                        {
                                            forbiddenVehicles.Insert(current.ID, vehicle);
                                        }
                                    }
                                }
                            }

                            graph.RemoveAbstractBus(e);
                            abstractBusses.Remove(e);
                        }

                        time += times.Get(current.ID);
                        double trueDist = distances.Get(current.ID) + distance;

                        if (!solved.ContainsValue(end) && current != end)
                        {
                            if (end.Latitude != 0 && end.Longitude != 0)
                            {
                                if (times.Get(end.ID) == 0 || distances.Get(end.ID) == 0)
                                {
                                    times.Insert(end.ID, double.PositiveInfinity);
                                    distances.Insert(end.ID, double.PositiveInfinity);
                                    vehicleUse.Insert(end.ID, v);
                                }

                                if ((mode == RouteMode.Fastest &&
                                     times.Get(end.ID) > time) ||
                                    (mode == RouteMode.Shortest &&
                                     distances.Get(end.ID) > trueDist))
                                {
                                    times.GetNode(end.ID).Content      = time;
                                    distances.GetNode(end.ID).Content  = trueDist;
                                    vehicleUse.GetNode(end.ID).Content = v;

                                    if (prevs.GetNode(end.ID).Content == null)
                                    {
                                        prevs.Insert(end.ID, current);
                                    }
                                    else
                                    {
                                        prevs.GetNode(end.ID).Content = current;
                                    }

                                    if (!unsolved.ContainsValue(end))
                                    {
                                        if (mode == RouteMode.Fastest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(times.Get(end.ID)))
                                            {
                                                times.GetNode(end.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(times.Get(end.ID), end);
                                        }
                                        else if (mode == RouteMode.Shortest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(distances.Get(end.ID)))
                                            {
                                                distances.GetNode(end.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(distances.Get(end.ID), end);
                                        }

                                        if (prevs.GetNode(current.ID).Content != null &&
                                            vehicleUse.Get(prevs.GetNode(current.ID).Content.ID) == Vehicle.Car)
                                        {
                                            if (v == Vehicle.Foot)
                                            {
                                                forbiddenVehicles.Insert(end.ID, Vehicle.Car);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else if (!solved.ContainsValue(start) && current != start)
                        {
                            if (start.Latitude != 0 && start.Longitude != 0)
                            {
                                if (times.Get(start.ID) == 0 || distances.Get(start.ID) == 0)
                                {
                                    times.Insert(start.ID, double.PositiveInfinity);
                                    distances.Insert(start.ID, double.PositiveInfinity);
                                    vehicleUse.Insert(start.ID, v);
                                }

                                if ((mode == RouteMode.Fastest &&
                                     times.Get(start.ID) > time) ||
                                    (mode == RouteMode.Shortest &&
                                     distances.Get(start.ID) > trueDist))
                                {
                                    times.GetNode(start.ID).Content      = time;
                                    distances.GetNode(start.ID).Content  = trueDist;
                                    vehicleUse.GetNode(start.ID).Content = v;

                                    if (prevs.GetNode(start.ID).Content == null)
                                    {
                                        prevs.Insert(start.ID, current);
                                    }
                                    else
                                    {
                                        prevs.GetNode(start.ID).Content = current;
                                    }


                                    if (!unsolved.ContainsValue(start))
                                    {
                                        if (mode == RouteMode.Fastest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(times.Get(start.ID)))
                                            {
                                                times.GetNode(start.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(times.Get(start.ID), start);
                                        }
                                        else if (mode == RouteMode.Shortest)
                                        {
                                            // Very bad solution but I couldn't think of a simple better one.
                                            while (unsolved.ContainsKey(distances.Get(start.ID)))
                                            {
                                                distances.GetNode(start.ID).Content += 0.0000000001;
                                            }

                                            unsolved.Add(distances.Get(start.ID), start);
                                        }
                                    }

                                    if (prevs.GetNode(current.ID).Content != null &&
                                        vehicleUse.Get(prevs.GetNode(current.ID).Content.ID) == Vehicle.Car)
                                    {
                                        if (v == Vehicle.Foot)
                                        {
                                            forbiddenVehicles.Insert(start.ID, Vehicle.Car);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                //dit zou niet voor moeten komen maar toch gebeurt het...
                if (!solved.ContainsKey(current.ID))
                {
                    solved.Add(current.ID, current);
                }

                if (unsolved.Count > 0)
                {
                    current = unsolved.Values[0];
                    unsolved.RemoveAt(0);
                }
                else
                {
                    current = null;
                }
            }


            if (found)
            {
                List <Node> nodes  = new List <Node>();
                List <long> extras = graph.GetExtras();
                Node        n      = destination;

                List <long> busStartStop = new List <long>();

                do
                {
                    bool foundRoute = false;

                    if (extras.Contains(n.ID))
                    {
                        // Change straigt buslines in for the actual route.
                        foreach (Edge e in graph.GetEdgesFromNode(n.ID))
                        {
                            if (prevs.Get(n.ID) != null && e.Route != null)
                            {
                                if (n.ID == e.Start &&
                                    prevs.Get(n.ID).ID == e.End)
                                {
                                    Node[] busNodes = e.Route.Points;

                                    if (busNodes[0].ID == e.Start)
                                    {
                                        Array.Reverse(busNodes);
                                    }

                                    busStartStop.Add(busNodes[busNodes.Length - 1].ID);
                                    busStartStop.Add(busNodes[0].ID);
                                    nodes.InsertRange(0, busNodes);


                                    n = prevs.Get(n.ID);

                                    foundRoute = true;
                                    break;
                                }
                                else if (n.ID == e.End &&
                                         prevs.Get(n.ID).ID == e.Start)
                                {
                                    Node[] busNodes = e.Route.Points;

                                    if (busNodes[0].ID == e.End)
                                    {
                                        Array.Reverse(busNodes);
                                    }

                                    busStartStop.Add(busNodes[busNodes.Length - 1].ID);
                                    busStartStop.Add(busNodes[0].ID);
                                    nodes.InsertRange(0, busNodes);


                                    n = prevs.Get(n.ID);

                                    foundRoute = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (!foundRoute)
                    {
                        nodes.Insert(0, n);
                        n = prevs.Get(n.ID);
                    }
                } while (n != null);


                result        = new Route(nodes.ToArray(), vehicles[0]);
                result.Time   = times.Get(destination.ID);
                result.Length = distances.Get(destination.ID);


                // Set bus as vehicle
                if (busStartStop.Count > 0)
                {
                    int    i           = busStartStop.Count - 1;
                    Node[] routePoints = result.Points;

                    for (int j = 0; j < routePoints.Length; j++)
                    {
                        if (routePoints[j].ID == busStartStop[i])
                        {
                            if (i % 2 == 1)
                            {
                                result.SetVehicle(Vehicle.Bus, j);
                                i--;
                            }
                            else
                            {
                                result.SetVehicle(Vehicle.Foot, j);
                                i--;
                            }
                        }

                        if (i < 0)
                        {
                            break;
                        }
                    }
                }

                Vehicle cur = result.GetVehicle(0), prev;
                for (int i = 2; i < result.NumOfNodes; i++)
                {
                    if (result.GetVehicle(i) != Vehicle.Bus)
                    {
                        prev = vehicleUse.Get(result[i].ID);

                        if (prev != cur && i > 1)
                        {
                            result.SetVehicle(prev, i - 1);
                        }

                        cur = prev;
                    }
                }
            }
            else
            {
                result        = new Route(new Node[] { source }, vehicles[0]);
                result.Time   = double.PositiveInfinity;
                result.Length = double.PositiveInfinity;
            }

            return(result);
        }