package com.tyczj.mapnavigator;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
public class Navigator {
@SuppressWarnings("unused")
private Context context;
private LatLng startPosition, endPosition;
private String mode;
private GoogleMap map;
private Directions directions;
private int pathColor = Color.BLUE;
private int secondPath = Color.CYAN;
private int thirdPath = Color.RED;
private float pathWidth = 5;
private OnPathSetListener listener;
private boolean alternatives = false;
private long arrivalTime;
private String avoid;
private ArrayList<Polyline> lines = new ArrayList<Polyline>();
public Navigator(GoogleMap map, LatLng startLocation, LatLng endLocation){
this.startPosition = startLocation;
this.endPosition = endLocation;
this.map = map;
}
public interface OnPathSetListener{
public void onPathSetListener(Directions directions);
}
public void setOnPathSetListener(OnPathSetListener listener){
this.listener = listener;
}
/**
* Gets the starting location for the directions
*
*/
public LatLng getStartPoint(){
return startPosition;
}
/**
* Gets the end location for the directions
*
*/
public LatLng getEndPoint(){
return endPosition;
}
/**
* Get's driving directions from the starting location to the ending location
*
* @param showDialog
* Set to true if you want to show a ProgressDialog while retrieving directions
* @param findAlternatives
* give alternative routes to the destination
*
*/
public void findDirections(boolean findAlternatives){
this.alternatives = findAlternatives;
new PathCreator().execute();
}
/**
* Sets the type of direction you want (driving,walking,biking or mass transit). This MUST be called before getting the directions
* If using "transit" mode you must provide an arrival time
*
* @param mode
* The type of directions you want (driving,walking,biking or mass transit)
* @param arrivalTime
* If selected mode it "transit" you must provide and arrival time (milliseconds since January 1, 1970 UTC). If arrival time is not given
* the current time is given and may return unexpected results.
*/
public void setMode(int mode, long arrivalTime,int avoid){
switch(mode){
case 0:
this.mode = "driving";
break;
case 1:
this.mode = "transit";
this.arrivalTime = arrivalTime;
break;
case 2:
this.mode = "bicycling";
break;
case 3:
this.mode = "walking";
break;
default:
this.mode = "driving";
break;
}
switch(avoid){
case 0:
this.avoid = "tolls";
break;
case 1:
this.avoid = "highways";
break;
default:
break;
}
}
/**
* Get all direction information
* @return
*/
public Directions getDirections(){
return directions;
}
/**
* Change the color of the path line, must be called before calling findDirections().
* @param firstPath
* Color of the first line, default color is blue.
* @param secondPath
* Color of the second line, default color is cyan
* @param thirdPath
* Color of the third line, default color is red
*
*/
public void setPathColor(int firstPath,int secondPath, int thirdPath){
pathColor = firstPath;
}
/**
* Change the width of the path line
* @param width
* Width of the line, default width is 3
*/
public void setPathLineWidth(float width){
pathWidth = width;
}
private Polyline showPath(Route route,int color){
return map.addPolyline(new PolylineOptions().addAll(route.getPath()).color(color).width(pathWidth));
}
public ArrayList<Polyline> getPathLines(){
return lines;
}
private class PathCreator extends AsyncTask<Void,Void,Directions>{
@Override
protected Directions doInBackground(Void... params) {
if(mode == null){
mode = "driving";
}
String url = "http://maps.googleapis.com/maps/api/directions/json?"
+ "origin=" + startPosition.latitude + "," + startPosition.longitude
+ "&destination=" + endPosition.latitude + "," + endPosition.longitude
+ "&sensor=false&units=metric&mode="+mode+"&alternatives="+String.valueOf(alternatives);
if(mode.equals("transit")){
if(arrivalTime > 0){
url += url + "&arrival_time="+arrivalTime;
}else{
url += url + "&departure_time="+System.currentTimeMillis();
}
}
if(avoid != null){
url += url+"&avoid="+avoid;
}
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost, localContext);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
String s = EntityUtils.toString(response.getEntity());
return new Directions(s);
}
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Directions directions){
if(directions != null){
Navigator.this.directions = directions;
for(int i=0; i<directions.getRoutes().size(); i++){
Route r = directions.getRoutes().get(i);
if(i == 0){
lines.add(showPath(r,pathColor));
}else if(i == 1){
lines.add(showPath(r,secondPath));
}else if(i == 3){
lines.add(showPath(r,thirdPath));
}
}
if(listener != null){
listener.onPathSetListener(directions);
}
}
}
}
}