Android: DrivingDirections removed since API 1.0 - how to do it in 1.5/1.6?

znq picture znq · Oct 23, 2009 · Viewed 10.8k times · Source

It seems that DrivingDirections have been removed since Android API 1.0

What's the way now to display a map with two points (one of them might be the current location, but can also be any other location) and the direction from one to another in Android 1.6?

Answer

Ben Shepherd picture Ben Shepherd · Nov 10, 2011

If you just need the point connected with a line you do not need the full kml. A much faster way to do it is to just use the JSON returned from Google Maps API with output=dragdir

private String getUrl(String start, String end) {
    //If params GeoPoint convert to lat,long string here
    StringBuffer urlString = new StringBuffer();
    urlString.append("http://maps.google.com/maps?f=d&hl=en");
    urlString.append("&saddr=");// from
    urlString.append(start);
    urlString.append("&daddr=");// to
    urlString.append(end);
    urlString.append("&ie=UTF8&0&om=0&output=dragdir"); //DRAGDIR RETURNS JSON
    Log.i("URLString", urlString.toString());
    return urlString.toString();
}

This urlString can be used to get a JSON file, which you can easily extract the information using String's split()

private String getConnection(String url) {
    URL inUrl = new URL(url);
    URLConnection yc = inUrl.openConnection();
    BufferedReader in = new BufferedReader( new InputStreamReader(yc.getInputStream()));
    String inputLine;
    String encoded = "";
    while ((inputLine = in.readLine()) != null)
        encoded = encoded.concat(inputLine);
    in.close();
    String polyline = encoded.split("points:")[1].split(",")[0];
    polyline = polyline.replace("\"", "");
    polyline = polyline.replace("\\\\", "\\");
    return polyline;
}

The returned String is a polyline which can be decoded into an list of Geopoints using the method below.

private static ArrayList<GeoPoint> decodePolyline(String encoded) {
    ArrayList<GeoPoint> geopoints = new ArrayList<GeoPoint>();
    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));
        geopoints.add(p);
    }
 return geopoints;
}

The last step is to draw these points to a mapView, for that we need an overlay item that will handle a ArrayList of GeoPoints.

public class PathOverlay extends Overlay {

    private ArrayList<GeoPoint> pointList;

    public PathOverlay(ArrayList<GeoPoint> pointList) {
            this.pointList = pointList;     
    }

    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        Point current = new Point();
        Path path = new Path();
        Projection projection = mapView.getProjection();
        Iterator<GeoPoint> iterator = pointList.iterator();
        if (iterator.hasNext()) {
            projection.toPixels(iterator.next(), current);
            path.moveTo((float) current.x, (float) current.y);
        } else return;
        while(iterator.hasNext()) {
            projection.toPixels(iterator.next(), current);
            path.lineTo((float) current.x, (float) current.y);
        }

        Paint pathPaint = new Paint();
        pathPaint.setAntiAlias(true);
        pathPaint.setStrokeWidth(3.0f);
        pathPaint.setColor(Color.GREEN);
        pathPaint.setStyle(Style.STROKE);
        canvas.drawPath(path, pathPaint);
    }
}

If your not sure about some of the intermediate steps, such as how to get the overlay onto the MapView or how to set up a router class let me know and I can send you the complete code.