I am using GoogleMapv2 api in my app. I want to draw a polygon line from source to destination. and show the travel time as well as distance on map activity but I am unable
I think the following code could help.
Routing.java
public class Routing extends AsyncTask<LatLng, Void, Route>
{
private final GoogleMap map;
private LatLng start;
private LatLng dest;
private final LatLngBounds.Builder builder = new LatLngBounds.Builder();;
private final int[] lineColor = { Color.GREEN };
private final int pos;
public Routing(final Activity activity, final GoogleMap map) {
super();
this.map = map;
this.pos = 0;
}
private TextView txtDistance;
public Routing(final Activity activity, final GoogleMap map, final TextView txtDistance) {
super();
this.map = map;
this.pos = 0;
this.txtDistance = txtDistance;
}
@Override
protected Route doInBackground(final LatLng... points) {
try {
start = points[0];
dest = points[1];
Parser parser;
final String jsonURL = "http://maps.googleapis.com/maps/api/directions/json?";
final StringBuffer sBuf = new StringBuffer(jsonURL);
sBuf.append("origin=");
sBuf.append(start.latitude);
sBuf.append(',');
sBuf.append(start.longitude);
sBuf.append("&destination=");
sBuf.append(dest.latitude);
sBuf.append(',');
sBuf.append(dest.longitude);
sBuf.append("&sensor=true&mode=driving");
System.out.println("sbuf: " + sBuf.toString());
parser = new GoogleParser(sBuf.toString());
final Route route = parser.parse();
return route;
} catch (final Exception e) {}
return null;
}
@Override
protected void onPreExecute() {
/** Empty Method */
}// end onPreExecute method
@SuppressLint("ResourceAsColor")
@Override
protected void onPostExecute(final Route result) {
try {
if (result == null) {
map.moveCamera(CameraUpdateFactory.newLatLngZoom(dest, 15));
map.animateCamera(CameraUpdateFactory.zoomTo(18), 2000, null);
} else {
final String text = result.getTextLength();
final String startAddress = result.getStartAddress().toString().trim().replaceAll(", ", ",\n");
final String endAddress = result.getEndAddress().toString().trim().replaceAll(", ", ",\n");
txtDistance.setVisibility(View.GONE);
if (text != null) {
txtDistance.setVisibility(View.VISIBLE);
txtDistance.setBackgroundResource(android.R.color.holo_orange_light);
txtDistance.setText(" Total Distance : " + text + "\n Total Duration : " + result.getDuration() + " ");
}
final List<LatLng> directionPoint = result.getPoints();
final PolylineOptions rectLine = new PolylineOptions().width(10).color(lineColor[pos]);
for (int i = 0; i < directionPoint.size(); i++) {
rectLine.add(directionPoint.get(i));
}
map.addPolyline(rectLine);
final Marker startLocation = map.addMarker(new MarkerOptions().position(start).title(startAddress).snippet("Main Location").icon(BitmapDescriptorFactory.fromResource(R.drawable.markera)));
final Marker endLocation = map.addMarker(new MarkerOptions().position(dest).title(endAddress).snippet("Destination Location").icon(BitmapDescriptorFactory.fromResource(R.drawable.markerb)));
builder.include(startLocation.getPosition());
builder.include(endLocation.getPosition());
final LatLngBounds bounds = builder.build();
// Pan to see all markers in view.
final int padding = 100; // offset from edges of the map in pixels
final CameraUpdate cup = CameraUpdateFactory.newLatLngBounds(bounds, padding);
map.moveCamera(cup);
map.animateCamera(cup);
}
} catch (final Exception e) {
e.printStackTrace();
}
}// end onPostExecute method
}
In your map activity add the following lines.
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (Utils.isGPSTurnOn(getApplicationContext())) {
onResume();
}
}
@Override
protected void onResume() {
super.onResume();
if (Utils.isConnected(getApplicationContext())) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.setMyLocationEnabled(true);
final TextView txtDistance = (TextView) findViewById(R.id.txtSpeed);
new Routing(getParent(), mMap, txtDistance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, start, end);
}
}
Utils.java
public class Utils
{
/**
* @Method used to checks if device having network connection or not.
* @param context the context
* @return <code>true</code> if the phone is connected
*/
public static boolean isConnected(final Context context) {
try {
final ConnectivityManager connMngr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo wifiNetwork = connMngr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifiNetwork != null && wifiNetwork.isConnectedOrConnecting()) { return true; }
final NetworkInfo mobileNetwork = connMngr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mobileNetwork != null && mobileNetwork.isConnectedOrConnecting()) { return true; }
final NetworkInfo activeNetwork = connMngr.getActiveNetworkInfo();
if (activeNetwork != null && activeNetwork.isConnectedOrConnecting()) { return true; }
} catch (final Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean isGPSTurnOn(final Context context) {
final LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
}
activity_map.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
<TextView
android:id="@+id/txtSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textStyle="bold"
android:text="@string/hello_world" />
</RelativeLayout>
You can get Trvelling time and distance with following code.. i have already use this code in one of my project hope this will help you
CalculateDistanceTime distance_task = new CalculateDistanceTime(getActivity());
distance_task.getDirectionsUrl(startLatLng, endLatLng);
distance_task.setLoadListener(new CalculateDistanceTime.taskCompleteListener() {
@Override
public void taskCompleted(String[] time_distance) {
approximate_time.setText("" + time_distance[1]);
approximate_diatance.setText("" + time_distance[0]);
}
});
and here is the CalculateDistanceTime class.
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class CalculateDistanceTime {
private taskCompleteListener mTaskListener;
private Context mContext;
public CalculateDistanceTime(Context context) {
mContext = context;
}
public void setLoadListener(taskCompleteListener taskListener) {
mTaskListener = taskListener;
}
public void getDirectionsUrl(LatLng origin, LatLng dest) {
// Origin of route
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
// Destination of route
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = str_origin + "&" + str_dest + "&" + sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Exception while downloading url", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
public interface taskCompleteListener {
void taskCompleted(String[] time_distance);
}
private class DownloadTask extends AsyncTask<String, Void, String> {
// Downloading data in non-ui thread
@Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
// Executes in UI thread, after the execution of
// doInBackground()
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
}
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
// Parsing the data in non-ui thread
@Override
protected List<HashMap<String, String>> doInBackground(String... jsonData) {
JSONObject jObject;
List<HashMap<String, String>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DistanceTimeParser parser = new DistanceTimeParser();
// Starts parsing data
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<HashMap<String, String>> result) {
String distance = "";
String duration_distance = "";
if (result.size() < 1) {
Log.e("Error : ", "No Points found");
return;
}
String[] date_dist = new String[2];
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
// Fetching i-th route
HashMap<String, String> tmpData = result.get(i);
Set<String> key = tmpData.keySet();
Iterator it = key.iterator();
while (it.hasNext()) {
String hmKey = (String) it.next();
duration_distance = tmpData.get(hmKey);
System.out.println("Key: " + hmKey + " & Data: " + duration_distance);
it.remove(); // avoids a ConcurrentModificationException
}
date_dist[i] = duration_distance;
}
mTaskListener.taskCompleted(date_dist);
}
}
}
and DistanceTimeparser
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DistanceTimeParser {
public List<HashMap<String, String>> parse(JSONObject jObject) {
List<HashMap<String, String>> routes = new ArrayList<HashMap<String, String>>();
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
jLegs = ((JSONObject) jRoutes.get(0)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(0)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("text"));
/** Getting duration from the json data */
jDuration = ((JSONObject) jLegs.get(0)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
routes.add(hmDistance);
routes.add(hmDuration);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
}
return routes;
}
}