Zurück zur Übersicht

Tobias Knell

14.06.2010

Routing / Driving directions on Android – Part 1: Get the route

Complementary to Sebastian’s posts about how to navigate with the MapView and how to add customized overlays to it, I want to show you, how you display the route between two points.

Well, the whole thing wouldn’t be a pain now, if google hadn’t removed the DrivingDirection class since API 1.0, with which you could solve this problem in no time and with just a few lines of code. But because they did remove it, we have to go through a little bit more trouble.

Getting started

First you have to realize, if you only need the coordinates of the route, or also driving directions like “go left on this street, drive right on that street…”.

The first step in both cases is to get the two locations between which the routing should happen. In our case we wanted to show the route from the current location of the user to our office, so one of the points is fixed:

synyxGeoPoint = new GeoPoint(49002175, 8394160);

And the user location is also quite easy to get:

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
Location lastKnownLocation =
locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));

With this we get the last known, accurate location of the user. So all there is left now, is to get the route.

Getting the geopoints from google maps

Kml (with driving directions)

If you need the driving directions, you can build yourself a url like this one to get a kml file with all the information:

http://maps.google.com/maps?f=d&hl=en&saddr=9.18333,48.7667&daddr=8.394160,49.002175&ie=UTF8&0&om=0&z=20&output=kml

(For the list of parameters of google maps, see here: mapki.com)

Here’s how we did it:


public String getUrl(GeoPoint src, GeoPoint dest){
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps?f=d&hl=en");
urlString.append("&saddr=");
urlString.append(Double.toString((double) src.getLatitudeE6() / 1.0E6));
urlString.append(",");
urlString.append(Double.toString((double) src.getLongitudeE6() / 1.0E6));
urlString.append("&daddr=");// to
urlString.append(Double.toString((double) dest.getLatitudeE6() / 1.0E6));
urlString.append(",");
urlString.append(Double.toString((double) dest.getLongitudeE6() / 1.0E6));
urlString.append("&ie=UTF8&0&om=0&output=kml");
return urlString;
}

The file you get from this url looks like this:


Hohenheimer Str./B27 to Karlstraße/L561
....
Head southeast on Hohenheimer Str./B27 toward Bopserwaldstraße Continue to follow B27
....
9.183560,48.766820,0.000000 9.183690,48.766670,0.000000 9.183640,48.766480,0.000000 9.183470,48.766380,0.000000
....

(the first number of each pair is the longitude, the second the latitude)

To convert them to GeoPoints use:

GeoPoint geoPoint = new GeoPoint((int)(Double.parseDouble(latitude[0])*1E6),(int)(Double.parseDouble(longitude[0])*1E6));

JSON (without driving directions)

If you don’t need the driving directions, you can save a few kilobytes by changing the output parameter to output=dragdir (else it’s exactly the same url as above) , which delivers you a json string with encrypted geopoints.

again an example of what the server returns:

{tooltipHtml:" (572x26#160;km / 5 hours 14 mins)",polylines:[{id:"route0",points:"se}bIgcwt@BSzA_D??Xh@dC|G??hDlIpBzFrAvC`@`BZjCV|@nApBtDvEx@rA| .....

So as you can see, you can’t just parse the string and get the geopoints out of it. You first have to decode them. Here’s a method that solves this for you (algorithm from http://facstaff.unca.edu/) :

// get only the encoded geopoints
encoded = encoded.split("points:"")[1].split("",")[0];
// replace two backslashes by one (some error from the transmission)
encoded = encoded.replace("\\", "\");
//decoding
List poly = new ArrayList();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;
        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;
            GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));
            poly.add(p);
        }

Getting the geopoints from open streetmap

You can also get the geopoints from open streetmap. It’s quite the same procedure, so i don’t write it all again.

Here you can see for yourself: YOURS Routing_API

What’s in the next post

That’s it for today, in the next post i will show you how to draw the route on your MapView properly.