Beispiel #1
0
        [Test] public void TreeEqualsSameTreeCell()
        {
            object actual = new ListTree(string.Empty, new [] { new ListTree("a") });
            Parse  table  = Parse.ParseFrom("<table><tr><td><ul><li>a</li></ul></td></tr></table>");

            Assert.IsTrue(IsEqual(table.Parts.Parts, actual));
        }
Beispiel #2
0
        public Graph(string path)
        {
            List<long>[,] geoBlocks = null;

            datasource = path;

            // Buffer is 1024 fileblocks big
            FileStream file = new FileStream(datasource, FileMode.Open, FileAccess.Read,
                                             FileShare.Read, 8 * 1024 * 1024);

            // List of file-positions where blocks with ways and/or
            // relations start.
            List<long> wayBlocks = new List<long>();

            // We will read the fileblocks in parallel
            List<long> blocks = new List<long>();

            List<long> busNodes = new List<long>();
            List<string> busNames = new List<string>();

            Console.WriteLine("Finding blocks");

            while (true)
            {
                long blockstart = file.Position;

                BlobHeader blobHead = readBlobHeader(file);
                if (blobHead == null)
                    break;

                if (blobHead.Type == "OSMHeader")
                {
                    HeaderBlock filehead = HeaderBlock.ParseFrom(
                        readBlockData(file, blobHead.Datasize));
                    for (int i = 0; i < filehead.RequiredFeaturesCount; i++)
                    {
                        string s = filehead.GetRequiredFeatures(i);
                        if (s != "DenseNodes" && s != "OsmSchema-V0.6")
                        {
                            throw new NotSupportedException(s);
                        }
                    }

                    // The .000000001 is 'cause longs are stored
                    fileBounds = new BBox(.000000001 * filehead.Bbox.Left,
                                          .000000001 * filehead.Bbox.Top,
                                          .000000001 * filehead.Bbox.Right,
                                          .000000001 * filehead.Bbox.Bottom);

                    horizontalGeoBlocks = (int)(fileBounds.Width / geoBlockWidth) + 1;
                    verticalGeoBlocks = (int)(fileBounds.Height / geoBlockHeight) + 1;
                    //Console.WriteLine("geoblocks {0}x{1}", horizontalGeoBlocks, verticalGeoBlocks);
                    
                    geoBlocks = new List<long>[horizontalGeoBlocks + 1,
                                               verticalGeoBlocks + 1];
                    wayGeoBlocks = new List<long>[horizontalGeoBlocks + 1,
                                               verticalGeoBlocks + 1];
                    landGeoBlocks = new List<long>[horizontalGeoBlocks + 1,
                                               verticalGeoBlocks + 1];
                    buildingGeoBlocks = new List<long>[horizontalGeoBlocks + 1,
                                               verticalGeoBlocks + 1];

                }
                else
                {
                    file.Position += blobHead.Datasize;

                    blocks.Add(blockstart);
                }
            }

            Console.WriteLine("Reading nodes");

            Parallel.ForEach(blocks, blockstart =>
            //foreach(long blockstart in blocks)
            {
                BlobHeader blobHead;
                byte[] blockData;

                lock (file)
                {
                    file.Position = blockstart;

                    blobHead = readBlobHeader(file);

                    // This means End Of File
                    if (blobHead == null || blobHead.Type == "OSMHeader")
                        throw new Exception("Should never happen");

                    blockData = readBlockData(file, blobHead.Datasize);
                }


                if (blobHead.Type == "OSMData")
                {

                    PrimitiveBlock pb = PrimitiveBlock.ParseFrom(blockData);

                    for (int i = 0; i < pb.PrimitivegroupCount; i++)
                    {
                        PrimitiveGroup pg = pb.GetPrimitivegroup(i);

                        if (pg.HasDense)
                        {
                            // Remember the start of every blob with nodes
                            nodeBlockIndexes.Insert(pg.Dense.GetId(0), blockstart);
                            long id = 0;
                            double latitude = 0, longitude = 0;
                            for (int j = 0; j < pg.Dense.IdCount; j++)
                            {
                                id += pg.Dense.GetId(j);
                                latitude += .000000001 * (pb.LatOffset +
                                                          pb.Granularity * pg.Dense.GetLat(j));
                                longitude += .000000001 * (pb.LonOffset +
                                                           pb.Granularity * pg.Dense.GetLon(j));

                                if (fileBounds.Contains(longitude, latitude))
                                {
                                    int blockX = XBlock(longitude);
                                    int blockY = YBlock(latitude);

                                    List<long> list = geoBlocks[blockX, blockY];
                                    if (list == null)
                                        geoBlocks[blockX, blockY] = list = new List<long>();
                                    list.Add(id);
                                }
                            }
                        }
                        else
                        {
                            wayBlocks.Add(blockstart);
                        }
                    }
                }
                //else
                    //Console.WriteLine("Unknown blocktype: " + blobHead.Type);

            });

            Console.WriteLine("Reading ways");

            Parallel.ForEach(blocks, blockstart =>
            //foreach(long blockstart in wayBlocks)
            {
                BlobHeader blobHead;
                byte[] blockData;

                lock (file)
                {
                    file.Position = blockstart;

                    blobHead = readBlobHeader(file);

                    // This means End Of File
                    if (blobHead == null || blobHead.Type == "OSMHeader")
                        throw new Exception("Should never happen");

                    blockData = readBlockData(file, blobHead.Datasize);
                }

                if (blobHead.Type == "OSMData")
                {
                    PrimitiveBlock pb = PrimitiveBlock.ParseFrom(blockData);
                    for (int i = 0; i < pb.PrimitivegroupCount; i++)
                    {
                        PrimitiveGroup pg = pb.GetPrimitivegroup(i);

                        /*
                         * Part one: read all the curves and add them
                         */

                        // Insert curves in the curve tree
                        for (int j = 0; j < pg.WaysCount; j++)
                        {
                            CurveType type = CurveType.UnTested;

                            OSMPBF.Way w = pg.GetWays(j);

                            // Nodes in this way
                            List<long> nodes = new List<long>();

                            long id = 0;
                            for (int k = 0; k < w.RefsCount; k++)
                            {
                                id += w.GetRefs(k);

                                nodes.Add(id);
                            }

                            string name = "";
                            int maxSpeed = 0;

                            bool makeCurve = true;
                            bool curveTypeSpecified = true;

                            bool carSpecified = false;
                            bool bicycleSpecified = false;
                            bool footSpecified = false;
                            bool busSpecified = false;

                            bool carAllowed = false;
                            bool bicycleAllowed = false;
                            bool footAllowed = false;
                            bool busAllowed = false;

                            for (int k = 0; k < w.KeysCount; k++)
                            {
                                string key = pb.Stringtable.GetS(
                                    (int)w.GetKeys(k)).ToStringUtf8();
                                string value = pb.Stringtable.GetS(
                                    (int)w.GetVals(k)).ToStringUtf8();

                                #region Process keys
                                switch (key.ToLower())
                                {
                                    #region highway
                                    case "highway":
                                        switch (value)
                                        {
                                            case "bus_guideway":
                                                type = CurveType.Bus_guideway;
                                                break;
                                            case "construction":
                                                type = CurveType.Construction_street;
                                                break;
                                            case "cycleway":
                                                type = CurveType.Cycleway;
                                                break;
                                            case "footway":
                                                type = CurveType.Footway;
                                                break;
                                            case "Living_street":
                                                type = CurveType.Living_street;
                                                break;
                                            case "motorway":
                                                type = CurveType.Motorway;
                                                break;
                                            case "motorway_link":
                                                type = CurveType.Motorway_link;
                                                break;
                                            case "pedestrian":
                                                type = CurveType.Pedestrian;
                                                break;
                                            case "primary":
                                                type = CurveType.Primary;
                                                break;
                                            case "primary_link":
                                                type = CurveType.Primary_link;
                                                break;
                                            case "proposed":
                                                type = CurveType.Proposed;
                                                break;
                                            case "raceway":
                                                type = CurveType.Raceway;
                                                break;
                                            case "residential":
                                                type = CurveType.Residential_street;
                                                break;
                                            case "road":
                                                type = CurveType.Road;
                                                break;
                                            case "secondary":
                                                type = CurveType.Secondary;
                                                break;
                                            case "secondary_link":
                                                type = CurveType.Secondary_link;
                                                break;
                                            case "service":
                                                type = CurveType.Service;
                                                break;
                                            case "steps":
                                                type = CurveType.Steps;
                                                break;
                                            case "tertiary":
                                                type = CurveType.Tertiary;
                                                break;
                                            case "tertiary_link":
                                                type = CurveType.Tertiary_link;
                                                break;
                                            case "track":
                                                type = CurveType.Track;
                                                break;
                                            case "trunk":
                                                type = CurveType.Trunk;
                                                break;
                                            case "trunk_link":
                                                type = CurveType.Trunk_link;
                                                break;
                                            case "unclassified":
                                                type = CurveType.Unclassified;
                                                break;
                                            case "path":
                                                type = CurveType.Path;
                                                break;
                                            default:
                                                //Console.WriteLine("TODO: highway=" + value);
                                                break;
                                        }
                                        break;
                                    #endregion
                                    #region landuse
                                    case "landuse":
                                        switch (value)
                                        {
                                            case "allotments":
                                                type = CurveType.Allotments;
                                                break;
                                            case "basin":
                                                type = CurveType.Basin;
                                                break;
                                            case "construction":
                                                type = CurveType.Construction_land;
                                                break;
                                            case "grass":
                                                type = CurveType.Grass;
                                                break;
                                            case "farm":
                                                type = CurveType.Farm;
                                                break;
                                            case "forest":
                                                type = CurveType.Forest;
                                                break;
                                            case "military":
                                                type = CurveType.Military;
                                                break;
                                            case "orchard":
                                                type = CurveType.Orchard;
                                                break;
                                            case "pond":
                                                type = CurveType.Salt_pond;
                                                break;
                                            case "recreation_centre":
                                                type = CurveType.Recreation_ground;
                                                break;
                                            default:
                                                //Console.WriteLine("TODO: landuse=" + value);
                                                break;
                                        }
                                        break;
                                    #endregion
                                    case "building":
                                        type = CurveType.Building;
                                        break;
                                    case "natural":
                                        if (value == "water")
                                            type = CurveType.Water;
                                        break;
                                    case "name":
                                    case "addr:housename":
                                    case "alt_name":
                                    case "loc_name":
                                    case "name_alt":
                                    case "name:left":
                                    case "name:right":
                                        if(name == "")
                                            name = value;
                                        else
                                            name = name + "/" + value;
                                        break;
                                    case "maxspeed":
                                        int.TryParse(value, out maxSpeed);
                                        break;
                                    case "bicycle":
                                    case "bicycle:backward":
                                    case "cyclestreet":
                                    case "cycleway":
                                    case "cycleway:lane":
                                    case "cycleway:left":
                                    case "cycleway:left:surface":
                                    case "cycleway:left:width":
                                    case "cycleway:right":
                                    case "cycleway:right:surface":
                                    case "cycleway:right:width":
                                    case "cycleway:surface":
                                    case "cycleway:width":
                                        bicycleSpecified = true;
                                        bicycleAllowed = value != "no";
                                        break;
                                    case "bicycle:oneway":
                                    case "oneway:bicycle":
                                    case "cycleway:oneway":
                                    case "oneway:cycleway:":
                                        bicycleSpecified = true;
                                        bicycleAllowed = true;
                                        break;
                                case "vehicle":
                                    bicycleSpecified = true;
                                    carSpecified = true;
                                    if(value == "no")
                                    {
                                        bicycleAllowed = false;
                                        carAllowed = false;
                                    }
                                    else
                                    {
                                        bicycleAllowed = true;
                                        carAllowed = true;
                                    }
                                    break;
                                case "car":
                                case "motorcar":
                                case "motor_vehicle":
                                    carSpecified = true;
                                    carAllowed = value != "no";
                                    break;
                                case "foot":
                                case "footway":
                                    footSpecified = true;
                                    footAllowed = value != "no";
                                    break;
                                    case "public_transport":
                                        type = CurveType.PublicTransportPlatform;
                                        break;
                                    case "bus":
                                        if(value != "no")
                                            type = CurveType.PublicServiceVehicles;
                                        break;
                                    case "waterway":
                                    case "water":
                                        // TODO? draw these things?
                                        // Or just the lake/basin/pond?
                                        if (value == "ditch" ||
                                           value == "drain" ||
                                           value == "weir" ||
                                           value == "stream"  ||
                                           value == "yes" ||
                                           value == "river" ||
                                           value == "culvert" ||
                                           value == "drain; culvert" ||
                                           value == "Ditch" ||
                                           value == "Tank_ditch" ||
                                           value == "dept_line" ||
                                           value == "lock" ||
                                           value == "canal"

                                            )
                                        {
                                           type = CurveType.Waterway;
                                        }
                                        if (
                                           value == "lake" ||
                                           value == "basin" ||
                                           value == "pond" ||
                                           value == "riverbank" 
                                            )
                                        {
                                            type = CurveType.Water;
                                        }
                                        break;
                                case "psv":
                                    if (value == "yes")
                                        type = CurveType.PublicServiceVehicles;
                                    break;
                                case "amenity":
                                    if (value == "parking")
                                    {
                                        type = CurveType.Parking;
                                        Coordinate center = FindCentroid(nodes);
                                        extras.Add(new Location(new Node(center.Longitude, center.Latitude, 0), LocationType.Parking));
                                    }
                                    break;
                                case "power":
                                    if (value == "generator")
                                        type = CurveType.Power;
                                    break;
                                default:
                                    if (key.StartsWith("building"))
                                    {
                                        type = CurveType.Building;
                                    }
                                    break;
                                }
                                #endregion
                            }

                            // Try to make sense of tags
                            #region Process transport tags
                            if (type.IsStreet())
                            {
                                // If type props don't match specified props
                                if(!curveTypeSpecified ||
                                   (bicycleSpecified &&
                                   (bicycleAllowed != type.BicyclesAllowed())) ||
                                   (carSpecified &&
                                   (carAllowed != type.CarsAllowed())) ||
                                   (footSpecified &&
                                   (footAllowed != type.FootAllowed())))
                                {
                                    // What is specified exactly?
                                    footAllowed = footSpecified ?
                                        footAllowed : type.FootAllowed();
                                    bicycleAllowed = bicycleSpecified ?
                                        bicycleAllowed : type.BicyclesAllowed();
                                    carAllowed = carSpecified ?
                                        carAllowed : type.CarsAllowed();

                                    // Tedious matching of stuff
                                    if(carAllowed)
                                    {
                                        if(footAllowed)
                                        {
                                            if (bicycleAllowed)
                                                type = CurveType.CarBicycleFoot;
                                        }
                                        else
                                        {
                                            if(bicycleAllowed)
                                                type = CurveType.CarBicycleNoFoot;
                                            else
                                                type = CurveType.Motorway;
                                        }
                                    }
                                    else
                                    {
                                        // What is specified exactly?
                                        footAllowed = footSpecified ?
                                            footAllowed : type.FootAllowed();
                                        bicycleAllowed = bicycleSpecified ?
                                            bicycleAllowed : type.BicyclesAllowed();
                                        carAllowed = carSpecified ?
                                            carAllowed : type.CarsAllowed();

                                        if(type == CurveType.PublicServiceVehicles)
                                        {
                                            if(footAllowed)
                                            {
                                                if(bicycleAllowed)
                                                    type = CurveType.BusFootBicycle;
                                                else
                                                    type = CurveType.BusFoot;
                                            }
                                            else
                                                type = CurveType.BusBicycle;
                                        }
                                        else
                                        {
                                            if(footAllowed && bicycleAllowed)
                                                type = CurveType.Path;
                                            if(footAllowed && !bicycleAllowed)
                                                type = CurveType.Footway;
                                            if(!footAllowed && bicycleAllowed)
                                                type = CurveType.NoCarBicycleNoFoot;
                                            if(!footAllowed && !bicycleAllowed)
                                                type = CurveType.NoneAllowed;
                                        }
                                    }
                                }
                            }
                            #endregion

                            if (makeCurve)
                            {
                                Curve c = new Curve(nodes.ToArray(), name);
                                c.Name = name;
                                c.Type = type;

                                if (type.IsStreet())
                                {
                                    foreach (long n in nodes)
                                    {
                                        ways.Insert(n, c);
                                    }

                                    if (maxSpeed > 0)
                                    {
                                        c.MaxSpeed = maxSpeed;
                                    }
                                }
                                else
                                {
                                if (type.IsBuilding())
                                    {
                                        foreach (long n in nodes)
                                        {
                                            buildings.Insert(n, c);
                                        }
                                    }
                                    else
                                    {
                                        foreach (long n in nodes)
                                        {
                                            lands.Insert(n, c);
                                        }
                                    }
                                }
                            }
                        }

                        /*
                         * Part two: adding bus routes and the likes
                         */

                        ListTree<long> endIdStartId = new ListTree<long>();

                        //Parallel.For(0, pg.RelationsCount, j =>
                        for(int j = 0; j < pg.RelationsCount; j++)
                        {
                            Relation rel = pg.GetRelations(j);

                            bool publictransport = false;
                            string name = "";

                            for (int k = 0; k < rel.KeysCount; k++)
                            {
                                string key = pb.Stringtable.GetS((int)rel.GetKeys(k)).ToStringUtf8();
                                string value = pb.Stringtable.GetS((int)rel.GetVals(k)).ToStringUtf8();

                                if (key == "route" && (value == "bus" ||
                                                      value == "trolleybus" ||
                                                      value == "share_taxi" ||
                                                      value == "tram"))
                                    publictransport = true;

                                if (key == "ref")
                                    name = value;
                            }

                            if (publictransport)
                            {
                                long id = 0;

                                //List<long> nodes = new List<long>();


                                for (int k = 0; k < rel.MemidsCount; k++)
                                {
                                    id += rel.GetMemids(k);
                                    string role = pb.Stringtable.GetS((int)rel.GetRolesSid(k)).ToStringUtf8();
                                    string type = rel.GetTypes(k).ToString();

                                    //Console.WriteLine(type + " " + id + " is " + role);
                                    if (type == "NODE" && role.StartsWith("stop"))
                                    {
                                        busNodes.Add(id);
                                        busNames.Add(name);
                                    }
                                }

                                for (int l = 0; l < busNodes.Count - 1; l++)
                                {
                                    Edge e = new Edge(busNodes[l], busNodes[l + 1]);
                                    e.Type = CurveType.AbstractBusRoute;

                                    if (!endIdStartId.Get(e.End).Contains(e.Start))
                                    {
                                        abstractBusWays.Add(e);
                                        endIdStartId.Insert(e.End, e.Start);
                                    }
                                }
                                Edge e2 = new Edge(busNodes[busNodes.Count - 1], 0);
                                e2.Type = CurveType.AbstractBusRoute;
                                abstractBusWays.Add(e2);
                                endIdStartId.Insert(busNodes[busNodes.Count - 1], 0);
                            }
                        }
                    }
                }
            });


            file.Close();

            Console.WriteLine("Sorting nodes");

            Parallel.For(0, horizontalGeoBlocks, (x) =>
                         {
                for(int y = 0; y <= verticalGeoBlocks; y++)
                {
                    if(geoBlocks[x, y] != null)
                    {
                        List<long> wayList = new List<long>();
                        List<long> landList = new List<long>();
                        List<long> buildingList = new List<long>();

                        foreach(long id in geoBlocks[x, y])
                        {

                            if(ways.Get(id).Count != 0)
                                wayList.Add(id);

                            if(lands.Get(id).Count != 0)
                                landList.Add(id);

                            if(buildings.Get(id).Count != 0)
                                buildingList.Add(id);
                        }

                        wayGeoBlocks[x, y] = wayList;
                        landGeoBlocks[x, y] = landList;
                        buildingGeoBlocks[x, y] = buildingList;
                    }
                }
            });


            Console.WriteLine("Routing busStations");
            // Add busstations
            for (int i = 0; i < busNodes.Count; i++)
            {
                if (busStations.Get(busNodes[i]) == null)
                {
                    Node n = GetNode(busNodes[i]);

                    if (n.Longitude != 0 && n.Latitude != 0)
                    {
                        busStations.Insert(busNodes[i], n);
                        extras.Add(new Location(n, LocationType.BusStation));
                    }
                }
            }

            busThread = new Thread(new ThreadStart(() => { LoadBusses(); }));
            busThread.Start();
        }
Beispiel #3
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;
        }