itinero / routing-api

An API based on Itinero.
MIT License
13 stars 16 forks source link

AddContracted #18

Open AlexW68 opened 5 years ago

AlexW68 commented 5 years ago

I have been using the API to get distances between two points in the UK for a while, the code works very well with no issues, I have been working on shortest distances, but now the requirement is to calculate both the shortest distance and fastest route at the same time so two router calculated at the same time, the processing time has gone from 1-3 seconds to 30+ seconds. I want to know if I am on the right track with doing the following:-

var routerDb2 = new RouterDb(); using (var stream = new FileInfo(@"d:\osrm\gb.osm.pbf").OpenRead()) { routerDb2.LoadOsmData(stream, Vehicle.Car); }

routerDb2.AddContracted(Vehicle.Car.Shortest()); routerDb2.AddContracted(Vehicle.Car.Fastest()); Router router2 = new Router(routerDb2);

using (var stream = new FileInfo(@"d:\osrm\contracted-gb.routerdb").Open(FileMode.Create, FileAccess.ReadWrite)) { routerDb2.Serialize(stream); stream.Flush(); stream.Close(); }

So adding two contractions into the same file, I did try building two files each with one contraction each but this was slow.

Then in Calculate doing the folllowing:-

    public Result<Route> Calculate(string type, Coordinate[] coordinates)
    {
        var fastest = Itinero.Osm.Vehicles.Vehicle.Car.Fastest();
        var shortest = Itinero.Osm.Vehicles.Vehicle.Car.Shortest();
        var points = new RouterPoint[coordinates.Length];
        if (type == "Fastest") {
            for (var i = 0; i < coordinates.Length; i++)
            {
                var result = _router.Router.TryResolve(fastest, coordinates[i], 200);
                if (result.IsError)
                {
                    result = _router.Router.TryResolve(fastest, coordinates[i], 2000);
                }
                if (result.IsError)
                {
                    result = _router.Router.TryResolve(fastest, coordinates[i], 20000);
                }
                points[i] = result.Value;
            }
            return _router.Router.TryCalculate(fastest, points);
        }
        else {
            for (var i = 0; i < coordinates.Length; i++)
            {
                var result = _router.Router.TryResolve(shortest, coordinates[i], 200);
                if (result.IsError)
                {
                    result = _router.Router.TryResolve(shortest, coordinates[i], 2000);
                }
                if (result.IsError)
                {
                    result = _router.Router.TryResolve(shortest, coordinates[i], 20000);
                }
                points[i] = result.Value;
            }
            return _router.Router.TryCalculate(shortest, points);
        }
    }

Or is it better to run two routers if so how do I change the port from 5000 to something else I could run one on 5000 (fastest) and one on 4000 (shortest), I have loads of RAM in the server so running two instances is not a problem.

Thank you for all your efforts, great piece of code!

xivk commented 5 years ago

I don't really see any mistakes in your code when glancing at it.

It should be just as fast with two contraction hier. in the routerdb. I would need more info/code to help you figure this out.

Are you 100% sure you have the contracted versions of the network in the loaded routerdb? You can use the debugger to check and make sure by stepping into the internals of the routerdb.

AlexW68 commented 5 years ago

Hi Ben,

Thank you very much for the email!

I will have a play later on this week trying to get this into one bit of code, I found out to load one instance onto another port so I have two apps running on my server one for quickest and one for shortest, its quick, sub 1 second for a 200 mile route that is before I switch the caching on which stores the distance in meters and the duration in minutes into the database so any coordinate pairs that match come out of the database rather than calculated, the cache keep the entries for 120 days then deletes them so its recalculated again after that.

I have a database of every postcode in the uk with the corresponding longitude and latitude so postcode to postcode distances can be done very quickly, happy to share if its any use to you.

I will let you know how I get on in the single code base at least I know I am on the right track.

Thanks again.

All The Best

Alex

On 29 Jul 2019, at 13:20, Ben Abelshausen notifications@github.com wrote:

I don't really see any mistakes in your code when glancing at it.

It should be just as fast with two contraction hier. in the routerdb. I would need more info/code to help you figure this out.

Are you 100% sure you have the contracted versions of the network in the loaded routerdb? You can use the debugger to check and make sure by stepping into the internals of the routerdb.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/itinero/routing-api/issues/18?email_source=notifications&email_token=AAU7N2CPBPUQIEAJ5QWZXQDQB3OAHA5CNFSM4IHO3FVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3AQXFQ#issuecomment-515967894, or mute the thread https://github.com/notifications/unsubscribe-auth/AAU7N2C4OWAYGS52DPB5STLQB3OAHANCNFSM4IHO3FVA.