Skip to content
karussell edited this page Feb 28, 2013 · 47 revisions

Try out

Try out GraphHopper with the following command which will make Unterfranken (part of Germany) routable:

./run.sh unterfranken.osm ui

  1. it downloads 40MB, unzips it to 450MB and creates road-files for graphhopper in unterfranken-gh (40MB)
  2. it builds the graphhopper jars
  3. if you leave the 'ui' away and specify osmreader.runshortestpath=true in the config.properties it'll run some shortest path queries on it
  4. if you want a faster, more comprehensive and beautiful UI then try out graphhopper-web!

When executing the command again, then the existing graphhopper road-files and jars will be used. So, the UI should pop up fast (~2 seconds). After the UI popped up you can drag to move the map or scroll to zoom like in ordinary maps apps. Click once to select a departure and another click to select the destination. Then a route should pop up like in this shiny image. Some more visualization of

Start Development

  • Run git clone https://github.com/graphhopper/graphhopper.git
  • Download maven
  • Open the project with NetBeans or enable Maven in your IDE

Use one of the following snippets to start development with GraphHopper

 // Initialization for the API to be used on a desktop or server pc
 GraphHopperAPI gh = new GraphHopper().forServer();
 gh.load("graph-hopper-folder");

 // Offline API on Android
 GraphHopperAPI gh = new GraphHopper().forAndroid();
 gh.load("graph-hopper-folder");

 // Online: Connect to your own hosted graphhopper web service, for GraphHopperWeb see graphhopper-web 
 GraphHopperAPI gh = new GraphHopperWeb();
 gh.load("http://your-graphhopper-service.com/api");

 
 GHRequest request = new GHRequest(new GeoPoint(fromLat, fromLon), new GeoPoint(toLat, toLon));
 request.algorithm("astar");
 GHResponse response = gh.route(request);
 print(response.distance() + " " + response.time());
 PointList points = response.createPoints();
 for(int i = 0; i < points.size(); i++) {
    add(point.latitude(i), point.longitude(i));
 }

If you want direct access to the more low-level API you can use this snippet. For more details on Android-usage have a look into this Android site

Create your UI

Notes

In order to integrate GraphHopper into your application you could use some lower level classes to get more power out of it. E.g. query the graph by a geo point (latitude,longitude) - for that you get one of the implementations of Location2IDIndex. Then use that point to query a RoutingAlgorithm implementation.

If you develop for Android have a look into graphhopper-android. For smallish graph (e.g. size of Berlin) use a RAMDataAccess driven GraphStorage (loads all into memory). For larger ones use the ContractionHierarchies preparation class and MMapDataAccess to avoid OutOfMemoryErrors.

If you develop a web application there is graphhopper-web. The simple API (json,jsonp,binary) in graphhopper-web is optimized regarding several aspects:

  • It tries to return a smallish data set (a JavaScript ArrayBuffer, gzip filter)
  • It enables cross-site scripting on the server- and client-site (jQuery, header setting)
  • It utilizes the new jquery deferred to chain ajax requests and avoids browser UI blocking.
  • To make things simple it uses the GeoCoder called Nominatim to get the name for a latitude+longitude point or vice versa.

Technical Overview

To get a better understanding also take a look in the source code, especially in the unit tests! There are mainly three parts:

1. The Algorithms

In the routing package you'll find all kind of shortest path algorithms like Dijkstra or A* etc. For those algorithms you need a graph.

At the moment every algorithm needs a kind of path extraction: from the shortest path tree one needs to determine the actual route, including the distance, time and exact latitude,longitude for every point. For bidirectional algorithms this is a bit more complicated and done in PathBidirRef. For Contraction Hierarchies one needs to additionally find the shortcutted node/edge and process this recursivly - this is done in Path4CH.

2. The Graph

To process algorihtms you need a Graph. At the moment there is one implementation GraphStorage which can be used:

  • in-memory with a safe option (RAMDataAccess) and
  • a memory mapped (MMapDataAccess).

The interface Graph is developed in the sense that the implementation can be as much efficient as possible - i.e. node ids and edge ids are successive (and so are just indices) and in the range of 0 to MAX-1. This design could be used to have an array-like structure in the underlying DataAccess implementation like it is currently the case.

The data layout is the following:

storage layout

Keep in mind that although the nodes 4 and 6 have no edges they still 'exist' and consume space in the current implementations of DataAccess.

The neo4j and tinkerpop implementations in graphhopper-experiments are highly experimental und no longer supported/recommended.

For some algorithms there are special implementations of the Graph. E.g. there is a LevelGraphStorage which is a Graph with the possibility to store shortcut edges and a level for every node. This special storage is necessary for Contraction Hierarchies. For this the graph needs also some preprocessing (which can take several hours for bigger areas) which is done in the OSMReader when configured (levelgraph=true and e.g. chShortcuts=fastest) or via API in PrepareContractionHierarchies. In order to use the shortcuts and get the benefits of the optimized graph you must use the algorithm returned from createAlgo() in the preparation class.

A subclass of GraphStorage cannot read normal GraphStorage files and vice versa. Also if GraphHopper version make major steps the storage files are not interchangable. Both is ensured via a version stamp in the file.

3. Data Import

The default import is done via OSMReader which imports OpenStreetMap data. You can configure it via API or use the run.sh script which utilizes the config.properties. You'll have to make sure that you allocate enough memory for your specific graph. The import process shouldn't take that long. E.g. complete germany with 30mio edges and 30mio nodes takes about 20 minutes on my oldish laptop. If you have more memory you can even avoid the double read and it'll take only 10minutes, so 1mio data entries in 10seconds.

Further Links

Clone this wiki locally