Help

GraphHopper in the Browser: TeaVM makes Offline Route Planning possible in JavaScript!

Today I can make an exciting news.

Alexey Andreev is the author of a Java-bytecode to Javascript compiler called TeaVM. You may know GWT or Scala.js but TeaVM does not compile the sources, it compiles the bytecode to JavaScript so you cannot only use Java as the source language. Of course other advantages exists.

Now after a chat with him and lots of work (he did), he finally reached the goal to run GraphHopper in the Browser, either via a normal bidirectional Dijkstra or a fast algorithm called Contraction Hierarchies – see below for a demo!

But what would be a use case?

You might think: “Boooring! Yet another project running in JavaScript!” – Well, far away from boring! Think about FirefoxOS which currently has no offline navigation. About a year ago I had a discussion with (probably) some FirefoxOS guys on hackernews about this topic. I did not really believed that something like this could be possible at that time, but now I’m really proud that I can say that GraphHopper with TeaVM is one step in this direction!

Another use case could be a hybrid solution with GraphHopper in the back end and GraphHopperJS on the client. So this opens up new possibilities!

There were lots of problems.

One of the problems Alexey solved already months before the GraphHopper stuff was the missing ‘long’-type support in JavaScript. TeaVM emulates this via a ‘lo’ and ‘hi’ structure. But this is rather simple compared to other tricks he had to apply.

Another, not yet really solved, problem is the file-access: how would you load the graph only partially into memory? In Java I can just use memory mapping if there is only a few RAM available. But is there memory mapping in the browser from JS? (Unanswered question on stackoverflow for over a week now). Currently Alexey stores the data as JSON in the html file, but this is too inefficient and wastes too much memory. Hopefully we can find a better solution – maybe IndexedDB could be part of this solution.

Why is this only the first step towards an offline Navigation?

For offline navigation you will need geocoding which turns address strings into coordinates and also offline maps:

  • For geocoding we would need a search engine like Lucene (Java) or something like my prototype of a JavaScript search engine called JSii (now I finally know a use case for this ;)). Additionally we need data, maybe consume OSM data from Nominatim or if it is just a city feed the streets directly to an index – this should be very easy.
  • Offline maps is not that hard because you could use data from GraphHopper itself to print the map for the current nearby area, although this will be inefficient for larger areas it will be sufficient for most navigation applications. There are already some powerful libraries for in-browser rendering available – see here.

Try GraphHopper in the Browser!

Warning: this will load the routing data for Greater London ~14MB and can take a while!

gh-teavm

If you zoom a bit in and out to cache the tiles, you can disconnect from the Internet and calculate offline routes anywhere! This should also work for mobile phones, of course calculating will be ‘slightly’ slower as Alex reported from 10x slower and even worse: on my old phone every browser I tried even crashed. Another minor bug is when you click outside of the routing area the app will stop working.

Get Started

Build teavm

  1. git clone TeaVM
  2. mvn clean package

Build GraphHopperJS

  1. git clone modified GraphHopper
  2. mvn clean package -DskipTests=true
  3. unzip target/graphhopper-teavm-0.3-SNAPSHOT-teavm.zip
  4. mv graphhopper-teavm-0.3-SNAPSHOT graphhopper-teavm
  5. Create a gh-directory.js via the GraphhopperJsonGenerator class and specify “<your-osm-file> gh-directory.js” as command line arguments. TODO: Uncomment the query part as this requires to have moscow area.
  6. cp gh-directory.js graphhopper-teavm
  7. firefox index.html (don’t enable firebug as this slows down everything!)

Next steps

  • I’ll try to integrate the changes Alexey did into GraphHopper for the next release.
  • Currently this is just for standalone usage and not accessible from “outside JavaScript” (already done via TeaVM @PreserveOriginalName ?)
  • Finally a fully navigation experience with geocoding and offline maps based on this work would be interesting.

Similar Projects

The only offline route planner in JavaScript I found was a public transport library called localroute, but not sure if it also works in the Browser. Let me know if there are similar projects as it is really hard to search for Routing & JavaScript 😉

Thanks!

A huge thanks to Alexey for making this possible – don’t forget to look into TeaVM !