dark_shadow
dark_shadow

Reputation: 3573

How to find optimal route between two points on google map and then highlight it?

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.

Upvotes: 4

Views: 5925

Answers (2)

Akhilesh Mani
Akhilesh Mani

Reputation: 3552

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;
}

Upvotes: 1

Waza_Be
Waza_Be

Reputation: 39577

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);
}
}

Upvotes: 1

Related Questions