4

Suppose I have two geolocations(points) on google map,now I want to highlight an optimal route between these two points through different cities.How can I do this ? I have searched on internet and found Drawing a line/path on Google Maps but this explains drawing a straight line between two points.I need to find route connecting different cites and at least the places which come in between two points.not a straight line.Can anyone give me some goodd tutorial or some idea how to do that ?

Answer: If any other person is facing same problem please see the accepted answer.To implement optimal route refer to http://csie-tw.blogspot.com/2009/06/android-driving-direction-route-path.html This is an excellent tutorial with working codes.You can modify them according to your need.And one more thing,while testing please give only those coordinates for which paths are possible(mistake that I was doing).Rest is all fine.Go ahead with the codes.Thanks.

Community
  • 1
  • 1
dark_shadow
  • 3,503
  • 11
  • 56
  • 81
  • Are you looking to use the Google Maps API to calculate the route, or are you trying to do that yourself with some network definition? – ViennaMike Nov 02 '11 at 17:42

2 Answers2

1

Yeah its right that am answering this question after long time. But I think this can help any other.

Put this code in onCreate or in your own method.

    MapView mv = (MapView)findViewById(R.id.mvGoogle);
    mv.setBuiltInZoomControls(true);
    MapController mc = mv.getController();
    //getDirections(lat1,lon2,lat2,lon2);
    ArrayList<GeoPoint> all_geo_points = getDirections(10.154929, 76.390316, 10.015861, 76.341867);
    if(all_geo_points.size()>0){
    GeoPoint moveTo = all_geo_points.get(0);
    mc.animateTo(moveTo);
    mc.setZoom(12);
    mv.getOverlays().add(new MyOverlay(all_geo_points));
    }else {
        Toast.makeText(getApplicationContext(), "Not able to show route !!", Toast.LENGTH_LONG).show();
    }

Now make your own custom overlay class.

    public class MyOverlay extends Overlay {
    private ArrayList<GeoPoint> all_geo_points;

    public MyOverlay(ArrayList<GeoPoint> allGeoPoints) {
        super();
        this.all_geo_points = allGeoPoints;
    }

    @Override
    public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
        super.draw(canvas, mv, shadow);
        drawPath(mv, canvas);
        return true;
    }

    public void drawPath(MapView mv, Canvas canvas) {
        int xPrev = -1, yPrev = -1, xNow = -1, yNow = -1;
        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setStrokeWidth(4);
        paint.setAlpha(100);
        if (all_geo_points != null) for (int i = 0; i < all_geo_points.size() - 4; i++) {
            GeoPoint gp = all_geo_points.get(i);
            Point point = new Point();
            mv.getProjection().toPixels(gp, point);
            xNow = point.x;
            yNow = point.y;
            if (xPrev != -1) {
                canvas.drawLine(xPrev, yPrev, xNow, yNow, paint);
            }
            xPrev = xNow;
            yPrev = yNow;
        }
    }
}

Now this method will give you all GeoPoints to draw route.I'll prefer to put this code in separate AsyncTask.

public static ArrayList<GeoPoint> getDirections(double lat1, double lon1, double lat2, double lon2) {
    String url = "http://maps.googleapis.com/maps/api/directions/xml?origin=" + lat1 + "," + lon1 + "&destination=" + lat2 + "," + lon2
            + "&sensor=false&units=metric";
    String tag[] = {"lat", "lng"};
    ArrayList<GeoPoint> list_of_geopoints = new ArrayList<GeoPoint>();
    HttpResponse response = null;
    try {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
        response = httpClient.execute(httpPost, localContext);
        InputStream in = response.getEntity().getContent();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(in);
        if (doc != null) {
            NodeList nl1, nl2;
            nl1 = doc.getElementsByTagName(tag[0]);
            nl2 = doc.getElementsByTagName(tag[1]);
            if (nl1.getLength() > 0) {
                list_of_geopoints = new ArrayList<GeoPoint>();
                for (int i = 0; i < nl1.getLength(); i++) {
                    Node node1 = nl1.item(i);
                    Node node2 = nl2.item(i);
                    double lat = Double.parseDouble(node1.getTextContent());
                    double lng = Double.parseDouble(node2.getTextContent());
                    list_of_geopoints.add(new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6)));
                }
            } else {
                // No points found
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return list_of_geopoints;
}
Akhilesh Mani
  • 3,502
  • 5
  • 28
  • 59
1

go through this codes. Modify the code as per ur requirement

//mapdirection.java
public class mapdirection extends MapActivity{

MapView mapview;
MapRouteOverlay mapoverlay;
Context _context;
List<Overlay> maplistoverlay;
Drawable drawable,drawable2;
MapOverlay mapoverlay2,mapoverlay3;
GeoPoint srcpoint,destpoint;
Overlay overlayitem;
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    setContentView(R.layout.map_direction);
    RegisterActivities.registerActivity(this);
    mapview=(MapView)this.findViewById(R.id.mapview);

    callMap();
}
private void callMap() {
      srcpoint=new GeoPoint((int)(Data.src_lat_date*1E6),(int)(Data.src_long_data*1E6));
      maplistoverlay=mapview.getOverlays();
      drawable=this.getResources().getDrawable(R.drawable.green_a);
      mapoverlay2=new MapOverlay(drawable);
      OverlayItem overlayitem = new OverlayItem(srcpoint, "", "");
      mapoverlay2.addOverlay(overlayitem);
      maplistoverlay.add(mapoverlay2);

      destpoint=new GeoPoint((int)(Data.dest_lat_data*1E6),(int)(Data.dest_long_data*1E6));
      drawable2=this.getResources().getDrawable(R.drawable.green_b);
      mapoverlay3=new MapOverlay(drawable2);
      OverlayItem overlayitem3 = new OverlayItem(destpoint, "", "");
      mapoverlay3.addOverlay(overlayitem3);
      maplistoverlay.add(mapoverlay3);


  double dest_lat = Data.dest_lat_data;
  double dest_long = Data.dest_long_data;

  GeoPoint srcGeoPoint = new GeoPoint((int) (Data.src_lat_date* 1E6),
  (int) (Data.src_long_data * 1E6));
  GeoPoint destGeoPoint = new GeoPoint((int) (dest_lat * 1E6),
  (int) (dest_long * 1E6));

  DrawPath(srcGeoPoint, destGeoPoint, Color.BLUE, mapview);

  mapview.getController().animateTo(srcGeoPoint);
  mapview.getController().setZoom(13);
  //mapview.setStreetView(true);
  mapview.setBuiltInZoomControls(true);
  mapview.invalidate();


}
private void DrawPath(GeoPoint src, GeoPoint dest, int color,
        MapView mMapView01) {

    // connect to map web service
    StringBuilder urlString = new StringBuilder();
    urlString.append("http://maps.google.com/maps?f=d&hl=en");
    urlString.append("&saddr=");//from
    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");
    Log.d("xxx","URL="+urlString.toString());

    //System.out.println(urlString);
    // get the kml (XML) doc. And parse it to get the coordinates(direction route).
    Document doc = null;
    HttpURLConnection urlConnection= null;
    URL url = null;
    try
    {
    url = new URL(urlString.toString());
    urlConnection=(HttpURLConnection)url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.connect();

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    doc = db.parse(urlConnection.getInputStream());

    if(doc.getElementsByTagName("GeometryCollection").getLength()>0)
    {
    //String path = doc.getElementsByTagName("GeometryCollection").item(0).getFirstChild().getFirstChild().getNodeName();
    String path = doc.getElementsByTagName("GeometryCollection").item(0).getFirstChild().getFirstChild().getFirstChild().getNodeValue() ;
    Log.d("xxx","path="+ path);
    String [] pairs = path.split(" ");
    String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude lngLat[1]=latitude lngLat[2]=height
    // src
    GeoPoint startGP = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble(lngLat[0])*1E6));
    //mMapView01.getOverlays().add(overlayitem);
    GeoPoint gp1;
    GeoPoint gp2 = startGP;
    for(int i=1;i<pairs.length;i++) // the last one would be crash
    {
    lngLat = pairs[i].split(",");
    gp1 = gp2;
    // watch out! For GeoPoint, first:latitude, second:longitude
    gp2 = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble(lngLat[0])*1E6));
    mMapView01.getOverlays().add(new MapRouteOverlay(gp1,gp2,2,color));
    Log.d("xxx","pair:" + pairs[i]);
    }
    //mMapView01.getOverlays().add(new MapRouteOverlay(dest,dest, 3)); // use the default color
    }
    }
    catch (MalformedURLException e)
    {
    e.printStackTrace();
    }
    catch (IOException e)
    {
    e.printStackTrace();
    }
    catch (ParserConfigurationException e)
    {
    e.printStackTrace();
    }
    catch (SAXException e)
    {
    e.printStackTrace();
    }       
}
@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}
//MapRouteOverlay.java

public class MapRouteOverlay extends Overlay {

private GeoPoint gp1;
private GeoPoint gp2;

private int mode=0;
private int defaultColor;

public MapRouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode) // GeoPoint is a int. (6E)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
defaultColor = 999; // no defaultColor

}

public MapRouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;
}

public int getMode()
{
return mode;
}

public boolean draw
(Canvas canvas, MapView mapView, boolean shadow, long when)
{
Projection projection = mapView.getProjection();
if (shadow == false)
{

Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(gp1, point);

if(mode==2)
{
if(defaultColor==999)
paint.setColor(Color.RED);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
}
return super.draw(canvas, mapView, shadow, when);
}
}
Girish Nair
  • 5,148
  • 5
  • 40
  • 61
Waza_Be
  • 39,407
  • 49
  • 186
  • 260
  • @ Profete 162 : What a co-incidence.Even I was looking at the same code at same time you posted it here.I guess this is the original link http://csie-tw.blogspot.com/2009/06/android-driving-direction-route-path.html .But I'm getting error with this code.Can you help me with these codes? I'm getting error in mapdirection.java on line : doc = db.parse(urlConnection.getInputStream()); Can you tell me what can be possible reason ? If you want I can post my logcat errors but after going through it I think the error comes in this line.Also I'm behind a proxy so I added few lines : – dark_shadow Nov 02 '11 at 20:00
  • System.setProperty("http.proxyHost", "my_host"); System.setProperty("http.proxyPort", "my_port"); System.setProperty("http.proxyUser", "my_username"); System.setProperty("http.proxyPassword", "My_password"); before openconnection() but not abled to figure out the prblem.Please help me. – dark_shadow Nov 02 '11 at 20:02
  • I'm pasting link for my logcat errors : http://pastebin.com/85npaZAi and link for my entire code : http://pastebin.com/FJ1inM73 Please see if there is anything that you can do ? – dark_shadow Nov 03 '11 at 12:28
  • LOL... Because there are no roads between your 2 points ;-) Please consider giving some points and vote for my answer, will motivate to help.. See this link for your issue:http://maps.google.com/maps?saddr=10.0,10.0&daddr=20.0,20.0&hl=fr&sll=37.0625,-95.677068&sspn=57.161276,82.705078&vpsrc=0&mra=ls&t=h&z=6 – Waza_Be Nov 03 '11 at 17:35
  • Sorry to say but it is still not working.This time I tried valid input like "27.11 78.11 " and "25.00 81.45" Can you help me what's going wrong.And I'll definitely vote up for your answer and will accept it but please help me.I'm really stuck here. – dark_shadow Nov 03 '11 at 20:10
  • please send your new loggat output – Waza_Be Nov 03 '11 at 22:33
  • This is my new logcat output but somehow I feel that problem is it is not abled to download KML file from internet but see if there is anything that I'm missing. http://pastebin.com/YE2eMYk4 – dark_shadow Nov 04 '11 at 09:03
  • You have added Internet permission to your application manifest? – Waza_Be Nov 04 '11 at 15:39
  • yes,I have added internet permissions but don't know what's going wrong ? Can you tell me is my code not abled to download KML file because I think this is the problem ? Can you tell me how can I see the KML file of routes as fetched from url ? – dark_shadow Nov 04 '11 at 16:25
  • kml file adress is at line 166 of your pastebin link and that works! I don't understand – Waza_Be Nov 04 '11 at 18:54
  • Finally it is working now.You were right we have to take those coordinates for which roads are possible.Thanks Profete 162 for the help and keeping my promise I'm voting up for your answer and accepting it.Sorry I can't vote up for you(don't have that much reputation) but accepted your answer. – dark_shadow Nov 04 '11 at 20:05
  • Glad to help people, because I often need help myself ;-D – Waza_Be Nov 04 '11 at 20:13