Getting started with Itinero, a route planning library for .NET
Itinero is an open-source project for .NET to calculate routes in a road network using OpenStreetMap data.
It was high on my list of things to try, so this week I made a little "Hello, world" console application to calculate the route between two geographic coordinates.
First I downloaded the OpenStreetMap data for the province of Quebec where I live. The file size is about 375MB.
I created a console application and added two Nuget package references to Itinero and Itinero.IO.Osm.
Before being usable by Itinero, the OSM data first needs to be transformed to Itinero's routerdb format:
var routerDb = new RouterDb();
using (var stream = new FileInfo("quebec-latest.osm.pbf").OpenRead())
{
// create the network for cars.
routerDb.LoadOsmData(stream, Vehicle.Car);
}
// write the routerdb to disk.
using (var stream = new FileInfo(@"quebec.routerdb").Open(FileMode.Create))
{
routerDb.Serialize(stream);
}
It took a few minutes to process the file on my computer. OSM files are updated daily so If I wanted to always have a routerdb with the latest data, this could quickly be automated with Azure Functions and a timer trigger.
Once we have a routerdb, we can use it to calculate a route:
RouterDb routerDb = null;
using (var stream = new FileInfo(@"quebec.routerdb").OpenRead())
{
routerDb = RouterDb.Deserialize(stream);
}
var router = new Router(routerDb);
// get a profile.
var profile = Vehicle.Car.Fastest(); // the default OSM car profile.
// create a routerpoint from a location.
// snaps the given location to the nearest routable edge.
var start = router.Resolve(profile, 45.532400f, -73.622885f);
var end = router.Resolve(profile, 45.545841f, -73.623474f);
// calculate a route.
var route = router.Calculate(profile, start, end);
using (var writer = new StreamWriter(@"route.geojson"))
{
route.WriteGeoJson(writer);
}
Here I generated a route between Montreal's Mount Royal and the airport, then saved the result to a GeoJSON file that you can see in this Gist.
The generated route is accurate, but the estimated travel time is too optimistic. Itinero gives 17 minutes whereas Google gives about 25 minutes in excellent traffic conditions. There's a GitHub issue open about this problem and apparently one way to address this is to build a custom vehicle profile.
Overall I'm pleased with the results and I think it is a very promising project that deserves more attention.