GraphHopper an Open Source and Cost Efficient Alternative to Google Maps API

On Monday we released version 0.2 of GraphHopper an Open Source road routing engine. GraphHopper is comparable fast to Google or Bing Maps, but if you use it in a LAN or directly from within your application it is a lot faster as it avoids the round trip over the internet, but furthermore if you need one-to-many or even many-to-many routes then GraphHopper is orders of magnitude faster. In this blog entry I’ll show you how to get everything you need to setup GraphHopper on your own servers.

Hosting GraphHopper on your own servers also means: you can query it as much as YOU like, currently this means 300 to 600 queries per second which is dependent on your hardware, of course. This is measured from real life car routes larger than 100km. Now, as you’ll set up a fault tolerant system with at least two servers this means you can put a load of over 100 mio requests per day on your system. This is 1000 times more than the limit of the Google Maps Business API and again: for one/many-to-many the benefits are even larger.

1. Install GraphHopper

Do so, either via our quick start docs or directly from the source which is my preferred way as you can easily stay up-to-date and try out minor code changes a lot faster. Although it will require that you’ve installed git and the JDK:

$ git clone git://github.com/graphhopper/graphhopper.git
$ cd graphhopper
$ ./graphhopper.sh web europe_germany_berlin.pbf

You should see this console output:

console-berlin-gh

It will start a jetty server on port 8989 – so if no exception occured you can go to http://localhost:8989 and if you clicked on two positions you should see the route for a car (default – can be changed in config.properties):

browser-berlin-gh

2. World Wide Routing Service

I assume you need car, pedestrian and bicycle routing for your personal world wide routing service. For this routing service you need two runtime servers (to make the system fault tolerant) and for each at least 52GB RAM. Additionally you need one ‘smaller’ preparation server with at least 32GB of RAM to prepare the graph for fast routing – you only need it for updating the OpenStreetMap data e.g. once a week. If you want to avoid this overhead then ask us as we already GraphHopper files regularly for world wide coverage.

Site notes:

  • In Germany there is at least one provider where you get those three servers for under 250€ per months.
  • If you cannot effort 2*64GB servers you could have a look into the memory mapped settings but this is slower – maybe not that slow via SSD, not yet deeply benchmarked.
  • If you don’t need the speed up, e.g. if your routes are rather small or you want a personalizable request then you ‘only’ need 2*12GB of RAM. Or less for the memory mapped case, which could even make it suitable for world wide routing on your 64bit Desktop! (Okay, still you need the geocoding and tiles, but that is for another blog post ;))

World Wide Download

On the preparation server download the OpenStreetMap data for the whole world e.g. from here. Then do

 ln -s planet-latest.pbf planet-car.pbf
 ln -s planet-latest.pbf planet-bike.pbf
 ln -s planet-latest.pbf planet-foot.pbf

Import and Prepare

Still on the preparation server import and prepare the GraphHopper folders for car

 export GH_WEB_OPTS="-Dgraphhopper.osmreader.acceptWay=CAR"
 export JAVA_OPTS="-XX:PermSize=100m -XX:MaxPermSize=100m -Xmx28000m -Xms28000m"
 ./graphhopper.sh import planet-car.pbf

Do the same for bike and foot . This process takes 1h for the import and 2 to 5h for the preparation – depending on the vehicle.

Start services

Zip the created GraphHopper routing files and copy them to the runtime servers. Then create startup scripts for every vehicle – e.g. for car routing is looks like:

 export JETTY_PORT=8900
 export GH_WEB_OPTS="-Dgraphhopper.osmreader.acceptWay=CAR"
 export JAVA_OPTS="-XX:PermSize=100m -XX:MaxPermSize=100m -Xmx16000m -Xms16000m"
 echo `date`
 cd /home/peter/graphhopper
 ./graphhopper.sh web ../data/planet-car.pbf >> web-car.log 2>&1

For bike you need a different JETTY_PORT, log file, acceptWay settings and slightly more RAM. The same for foot. You can now start the three scripts either via screen or nohub or your tool of choice to send scripts to the background.

Merge JVMs

On every runtime server you need to set up nginx to ‘merge’ those three JVMs to create one API where you only change the vehicle URL parameter. Here is an excerpt from my /etc/nginx/sites-enabled/default config:

server {
 ...
 # a simple trick to merge the three vehicles into one API
 location = /routing/api/info {
   add_header Content-Type "application/json";
   echo $arg_callback '({"buildDate":"2013-07-19T00:00","bbox":[-180,-79.81499965820461,180,82.5127018432178],"version":"0.1","supportedVehicles":"CAR,BIKE,FOOT"});';
 }
 location /routing {
   proxy_redirect  off;
   if ($arg_vehicle = "") {
    proxy_pass http://localhost:8900;
   }
   if ($arg_vehicle = "car") {
    proxy_pass http://localhost:8900;
   }
   if ($arg_vehicle = "bike") {
    proxy_pass http://localhost:8901;
   }
   if ($arg_vehicle = "foot") {
    proxy_pass http://localhost:8902;
   }
   rewrite ^/routing(.*) $1 break;
 }
 ...
} # server

3. Move to Leaflet and GraphHopper

Finally your client code needs to move away from Google Maps. Have a look into this description how to handle leaflet in general and into our own code how to handle the routing. Vote +1 for this issue to avoid this work :). Additionally to JavaScript we also provide a pure Java API useful for in-app communication.

Conclusion

Although GraphHopper is not yet feature complete it can already offer a production ready road routing service which is also easy to set up. Furthermore GraphHopper won’t take high administration costs as it is already very robust and used under high load in some companies for several months.

Last but not least GraphHopper is easy to customize and can satisfy a wide range of different business needs.

2 thoughts on “GraphHopper an Open Source and Cost Efficient Alternative to Google Maps API

  1. Pingback: Weekly OSM Summary #83 | OpenStreetMap Blog

  2. Pingback: OpenStreetMap Chile » Blog Archive » Resumen Semanal OSM #83

Comments are closed.