I am an android noob and i am exploring android maps api.I am referring this site.
I can understand everything except the distance and duration retrieval.
The JSON parsing code is given below.
public List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONArray jSteps = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).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(j)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
/** Adding distance object to the path */
path.add(hmDistance);
/** Adding duration object to the path */
path.add(hmDuration);
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
/** Traversing all steps */
for(int k=0;k<jSteps.length();k++){
String polyline = "";
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
/** Traversing all points */
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
path.add(hm);
}
}
}
routes.add(path);
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes;
}
They are getting distance and duration data for every single leg.The Android docs says , distance indicates the total distance covered by this leg and "duration indicates the total duration of this leg".So my assumption was, during final distance and duration computaion,
all these datum would be added.
This is the final code:
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
if(result.size()<1){
Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show();
return;
}
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
if(j==0){ // Get distance from the list
distance = (String)point.get("distance");
continue;
}else if(j==1){ // Get duration from the list
duration = (String)point.get("duration");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(2);
lineOptions.color(Color.RED);
}
tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration);
// Drawing polyline in the Google Map for the i-th route
map.addPolyline(lineOptions);
}
}
My assumption went wrong.Here the distance and duration are retrieved for every leg(they are not even stored) and after looping through every route and leg ,finally the textview is set to those variables(distance and duration) and it gives the overall distance and duration.
So my question is how the overall distance and duration are computed without any manual mathematical operations,while we have parsed those objects corresponding to all individual legs?
use distance matrix api to get the actual distance and time . see the bellow link
https://developers.google.com/maps/documentation/distance-matrix/start
Related
I am drawing route on google map using waypoints. Everything looks good except my origin and destination is also connected. I am sure my origin and destination is not same.
Here is the url generated after I generate directions url from list of latitude/longitudes.
https://maps.googleapis.com/maps/api/directions/json?
&origin=26.8530478,75.78491989999999
&destination=26.8804683,75.75850109999999
&waypoints=26.8566917,75.7691974%7C
26.868405,75.76440269999999%7C
26.8762989,75.7664082
&key=MY_API_KEY
And also attaching the output. The straight line from "1" to "5' should not be there. Please help me in finding the mistake.
Thanks.
ParserTask -
ArrayList<LatLng> points = new ArrayList<LatLng>();
PolylineOptions lineOptions = new PolylineOptions();
// LatLngBounds.Builder builder = new LatLngBounds.Builder();
int color = ContextCompat.getColor(activity, R.color.black_overlay);
if (null != result)
for (int i = 0; i < result.size(); i++) {
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
//builder.include(position);
}
lineOptions = new PolylineOptions().width(15).color(color).addAll(points).zIndex(6);
}
if (activity instanceof OnRoutesParsingCompletedCallBack) {
((OnRoutesParsingCompletedCallBack) activity).
onRoutesParsingCompleted(lineOptions);
}
Activity with map object -
#Override
public void onRoutesParsingCompleted(PolylineOptions lineOptions) {//}, LatLngBounds.Builder builder) {
if (lineOptions.getPoints().size() > 0) {
googleMap.addPolyline(lineOptions);
} else
Toast.makeText(this, "There is something wrong. No routes to draw!", Toast.LENGTH_SHORT).show();
mCurrLocationMarker.showInfoWindow();
progressBar.setVisibility(GONE);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLong, 13));
}
I think, the issue is that you are adding all possible routes to the same polyline. So, the polyline goes by the first route, then it "returns" to the start point and goes again by the second route. You either need to remove the for that loops over the results:
if (null != result)
// Fetching 1st route
List<HashMap<String, String>> path = result.get(0);
// Fetching all the points in 1st route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
//builder.include(position);
}
lineOptions = new PolylineOptions().width(15).color(color).addAll(points).zIndex(6);
}
Or you can create a polyline for each existing route.
Google Directions Api: https://maps.googleapis.com/maps/api/directions/json?origin=1.29068,103.851743&destination=1.324298,103.9032129&sensor=false&mode-driving&alternatives=true
There are 3 routes in the link, but I have to edit my code to process and display through all 3 routes. I am trying to find the shortest route, route that avoid tolls, and the fastest route (which i believe is the default one provided by google)
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... strings) {
JSONObject jsonObject;
List<List<HashMap<String, String>>> routes = null;
try {
jsonObject = new JSONObject(strings[0]);
DirectionsJSONParser directionsJSONParser = new DirectionsJSONParser();
routes = directionsJSONParser.parse(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
return routes;
}
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> lists) {
//Get list route and display
ArrayList points = null;
PolylineOptions polylineOptions = null;
String distance = "";
String duration = "";
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i = 0; i < lists.size(); i++) {
points = new ArrayList();
polylineOptions = new PolylineOptions();
List<HashMap<String, String>> path = lists.get(i);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
if(j==0){ // Get distance from the list
distance = point.get("distance");
continue;
}else if(j==1){ // Get duration from the list
duration = point.get("duration");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
boundsBuilder.include(position);
}
polylineOptions.addAll(points);
polylineOptions.width(12);
polylineOptions.color(Color.RED);
polylineOptions.geodesic(true);
}
if (polylineOptions != null) {
mMap.addPolyline(polylineOptions);
LatLngBounds routeBounds = boundsBuilder.build();
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(routeBounds, 12));
mDisTextView.setText(distance);
mDuraTextView.setText(duration);
} else {
Toast.makeText(MapActivity.this, "Directions not found!", Toast.LENGTH_SHORT).show();
}
}
Here is my JSONParser class
public List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONArray jSteps = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).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(j)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
/** Adding distance object to the path */
path.add(hmDistance);
/** Adding duration object to the path */
path.add(hmDuration);
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
/** Traversing all steps */
for(int k=0;k<jSteps.length();k++){
String polyline = "";
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List list = decodePoly(polyline);
/** Traversing all points */
for(int l=0;l <list.size();l++){
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes;
}
/**
* Method to decode polyline points
* Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
* */
private List decodePoly(String encoded) {
List poly = new ArrayList();
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;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
}
I am assuming that if you set alternatives to true, the API is going to return multiple route objects. Given that you simply need to loop through the array of route objects and sort them based on their total length (distance).
-By Default Google provide you shortest path if you set this key to false google gives you the shortest path alternatives=false
and if you want alternatives then you have to set below key to direction API:
-Unfortunately, there is not currently a way to have the API return the absolute shortest route in all situations.
but using avoid key in the direction API you are able to find the shortest route like below options:
Google Directions Api:
https://maps.googleapis.com/maps/api/directions/json?origin=1.29068,103.851743&destination=1.324298,103.9032129&avoid=highways&sensor=false&mode-driving&alternatives=true
on my app i add 2 marker on map. When i add a second marker with click i call a function to calculate route and add polyline on map.
This is the code for polyline
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
String value_duration = "";
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
if (j == 0) { // Get distance from the list
distance = (String) point.get("distance");
continue;
} else if (j == 1) { // Get duration from the list
duration = (String) point.get("duration");
value_duration = (String) point.get("duration_");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.parseColor("#F7B907"));
}
// Drawing polyline in the Google Map for the i-th route
distanza_percorso = distance;
durata_percorso = duration;
testo_car.setText(durata_percorso);
durata_tragitto = Float.parseFloat(value_duration);
Log.d("durata_tragitto", "durata: " + value_duration);
polylineFinal = map.addPolyline(lineOptions);
moveToBounds(map.addPolyline(lineOptions));
}
Now i would like to remove polyline by map if i replace second marker and call a new calculate route.
I have write this codde:
if (polylineFinal != null){
polylineFinal.remove();
}
but the polyline on map are not remove.
Can you help me please? Any idea why?
Thanks
Not sure but try updating your adding polyline code with this,
polylineFinal = map.addPolyline(lineOptions);
moveToBounds(polylineFinal);
I want to draw path of my lat long position on a map from SQLite. Is it possible and can anyone help me with this on Android? I've attached my map activity for location.
You can try this
PolylineOptions rectOptions = new PolylineOptions()
.add(new LatLng(37.35, -122.0))
.add(new LatLng(37.45, -122.0)) // North of the previous point, but at the same longitude
.add(new LatLng(37.45, -122.2)) // Same latitude, and 30km to the west
.add(new LatLng(37.35, -122.2)) // Same longitude, and 16km to the south
.add(new LatLng(37.35, -122.0)); // Closes the polyline.
// Get back the mutable Polyline
Polyline polyline = myMap.addPolyline(rectOptions);
or for database
Cursor cursor = database,getData("your query");
PolylineOptions rectOptions = new PolylineOptions();
if(cursor!=null && cursor.getCount()>0 && cursor.moveToFirst())
{
do
{
String lt = cursor.getString(curor.getColumnIndex("columnName"));
double lat = Double.parseDouble(lt);
String ln = cursor.getString(curor.getColumnIndex("columnName"));
double lng = Double.parseDouble(ln);
rectOptions.add(new LatLng(lat, lng)); // Closes the polyline.
// Get back the mutable Polyline
}while(cursor.moveToNext());
}
Polyline polyline = myMap.addPolyline(rectOptions);
**Create Seperate class**
class DirectionsJSONParser {
/**
* Receives a JSONObject and returns a list of lists containing latitude and longitude
*/
public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String, String>>>();
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONObject jDistance = null;
JSONArray jSteps = null;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for (int i = 0; i < jRoutes.length(); i++) {
jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for (int j = 0; j < jLegs.length(); j++) {
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("value"));
jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
/** Adding distance object to the path */
path.add(hmDistance);
/** Traversing all steps */
for (int k = 0; k < jSteps.length(); k++) {
String polyline = "";
polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
/** Traversing all points */
for (int l = 0; l < list.size(); l++) {
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat", Double.toString(((LatLng) list.get(l)).latitude));
hm.put("lng", Double.toString(((LatLng) list.get(l)).longitude));
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
}
return routes;
}
/**
* Method to decode polyline points
* Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
*/
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<LatLng>();
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;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
}
- **In Activtiy**
private String 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;
return url;
}
// Fetches data from url passed
private class DownloadTask extends AsyncTask<String, Void, String> {
// Downloading data in non-ui thread
#Override
protected String doInBackground(String... url1) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(url1[0]);
// 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));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d(TAG, e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
} catch (Exception e) {
Log.d(TAG, e.toString());
}
return data;
}
#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<List<HashMap<String, String>>>> {
// Parsing the data in non-ui thread
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// 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<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points;
PolylineOptions lineOptions = null;
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
if (j == 0) { // Get distance from the list
String dist = point.get("distance");
if(dist!=null && dist.length()>0) {
int distInt = Integer.parseInt(dist);
sumDistance += distInt;
}
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.BLUE);
}
mGoogleMap.addPolyline(lineOptions);
if (true) {
// Drawing polyline in the Google Map for the i-th route
mGoogleMap.addPolyline(lineOptions);
}
//Log.d(TAG, "map: " + map + " lineoptions: " + lineOptions);
}
}
calling:
String url = getDirectionsUrl(position, position1);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
I am building an android application where I am using google map API to get distance and time between two lat,lng. The problem is sometime I am getting the value in KM and some time in meter.
Is there any way to fix the unit of distance and time value returning from google API.
Here is my code.
public class DirectionsJSONParser {
/** Receives a JSONObject and returns a list of lists containing latitude and longitude */
public List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONArray jSteps = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).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(j)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
/** Adding distance object to the path */
path.add(hmDistance);
/** Adding duration object to the path */
path.add(hmDuration);
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
/** Traversing all steps */
for(int k=0;k<jSteps.length();k++){
String polyline = "";
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
/** Traversing all points */
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
path.add(hm);
}
}
}
routes.add(path);
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes;
}
/**
* Method to decode polyline points
* Courtesy : jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
* */
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<LatLng>();
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;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
Here the the function where I get the distance and time in a string.
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
// Parsing the data in non-ui thread
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// 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<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
if (result.size() < 1) {
Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show();
return;
}
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
if (j == 0) {
// Get distance from the list
distance = (String) point.get("distance");
continue;
} else if (j == 1) { // Get duration from the list
duration = (String) point.get("duration");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.BLUE);
}
Toast.makeText(getApplicationContext(), "Distance:" + distance + ", Duration:" + duration, Toast.LENGTH_LONG).show();
map.addPolyline(lineOptions);
}
}
I need is that the final that return should be KM in distance and HH:MM in hr.
From your code, looks like you are getting results from the Direction Web API.
In your code,
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("text"));
Notices that you are getting the human-readable distance "text", rather than the integer value value.
Look at this piece of JSON from the example in the documentation
...
},
"distance": {
"value": 2137146,
"text": "1,328 mi"
},
"start_loc...
...
Here, ..leg[0].distance.text is the human-readable value in miles. What you should get instead is the integer value ..leg[0].distance.value, which is always in meter.
So in short, get the value in meter, not the text.