I have added a waypoint and drawn the polyline from start to destination through the waypoint. But an extra straight line is drawn from start to destination. How can I remove it ?
The code below shows the ParserTask and getDirections URL.
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();
routes = parser.parse(jObject);
Log.d("routes", routes.toString());
Log.d("jObject", jObject.toString());
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = new ArrayList<LatLng>();;
PolylineOptions lineOptions = new PolylineOptions();;
lineOptions.width(2);
lineOptions.color(Color.RED);
MarkerOptions markerOptions = new MarkerOptions();
// Traversing through all the routes
for(int i=0;i<result.size();i++){
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
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);
}
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.RED);
lineOptions.geodesic(true);
}
// Drawing polyline in the Google Map for the i-th route
mMap.addPolyline(lineOptions);
}
}
private String getDirectionsUrl(LatLng origin_start, LatLng dest, LatLng waypoint_xx) {
String origin = "origin=" + origin_start.latitude + "," + origin_start.longitude;
//String waypointss = "waypoints=optimize:true|" + waypoint_xx.latitude + "," + waypoint_xx.longitude ;
String destination = "destination=" + dest.latitude + "," + dest.longitude;
// Waypoints
String waypoints = "";
for(int i=2;i<markerPoints.size();i++){
LatLng point = (LatLng) markerPoints.get(i);
if(i==2)
waypoints = "waypoints=";
waypoints += point.latitude + "," + point.longitude + "|";
}
String sensor = "sensor=false";
String alternative = "alternatives=false";
String params = origin + "&" + destination + "&" + alternative + "&" + sensor + "&" + waypoints ;
String output = "json";
String url = "https://maps.googleapis.com/maps/api/directions/"
+ output + "?" + params;
return url;
}
This code is the Directions JSON Parser
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;
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++){
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;
}
}
This is the Download Task
private class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... url) {
String data = "";
try {
data = downloadUrl(url[0]);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
Log.d("parserTask data", data.toString());
return data;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
Log.d("parserTask result", result.toString());
parserTask.execute(result);
}
}
And finally the onMapReady method
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
UiSettings uiSettings = googleMap.getUiSettings();
//uiSettings.setCompassEnabled(false);
uiSettings.setZoomControlsEnabled(true);
//-------------
// mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
//-------------
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference().child("location");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(MapsActivity.this)
.setSmallIcon(R.drawable.applogo)
.setContentTitle("Trip Request")
.setContentText("Click to accept trip!");
manager = (NotificationManager) MapsActivity.this.getSystemService( MapsActivity.this.NOTIFICATION_SERVICE );
manager.notify(0, builder.build());
// sendNotification();
startLatFB = (Double) dataSnapshot.child("startLat").getValue();
startLonFB = (Double) dataSnapshot.child("startLon").getValue();
endLatFB = (Double) dataSnapshot.child("endLat").getValue();
endLonFB = (Double) dataSnapshot.child("endLon").getValue();
Log.d("startLat", startLatFB.toString());
Log.d("startLon", startLonFB.toString());
Log.d("endLat", endLatFB.toString());
Log.d("endLon", endLonFB.toString());
if (markerPoints.size() > 1) {
markerPoints.clear();
mMap.clear();
}
double startLat = startLatFB; //SLIIT
double startLon = startLonFB;
double wayPointLat = 6.9040322; //FAB - Malabe
double wayPointLon = 79.948803;
double wayPointLatTwo = 6.053519; //FAB - Malabe
double wayPointLonTwo = 80.220977;
double endLat = endLatFB; //MAS
double endLon = endLonFB;
LatLng start_latLng = new LatLng(startLat, startLon);
LatLng waypoint_latLng = new LatLng(wayPointLat, wayPointLon);
LatLng end_latLng = new LatLng(endLat, endLon);
// LatLng start_latLng = new LatLng(startLatFB, startLonFB);
// LatLng waypoint_latLng = new LatLng(wayPointLat, wayPointLon);
// LatLng end_latLng = new LatLng(endLatFB, endLonFB);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(start_latLng, 11));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(start_latLng,11f));
// start_latLng = startLatFB;
// Adding new item to the ArrayList
markerPoints.add(start_latLng);
markerPoints.add(end_latLng);
markerPoints.add(waypoint_latLng);
// Creating MarkerOptions
MarkerOptions options = new MarkerOptions();
MarkerOptions optionsTwo = new MarkerOptions();
MarkerOptions optionsThree = new MarkerOptions();
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.startlocation);
BitmapDescriptor icon2 = BitmapDescriptorFactory.fromResource(R.drawable.endlocation);
// Setting the position of the marker
options.position(start_latLng);
optionsTwo.position(end_latLng);
optionsThree.position(waypoint_latLng);
if (markerPoints.size() == 1) {
options.icon(icon);
} else if (markerPoints.size() == 2) {
options.icon(icon2);
}
// Add new marker to the Google Map Android API V2
mMap.addMarker(options);
mMap.addMarker(optionsTwo);
mMap.addMarker(optionsThree);
// Checks, whether start and end locations are captured
if (markerPoints.size() >= 3) {
LatLng origin = (LatLng) markerPoints.get(0);
LatLng dest = (LatLng) markerPoints.get(1);
LatLng waypointss = (LatLng) markerPoints.get(2);
Log.d("origin url", origin.toString());
Log.d("dest url", origin.toString());
Log.d("waypoint url", origin.toString());
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest, waypointss);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
Log.d("DownloadTask url", url);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Try initializing new Arraylist of Points each time while traversing.
Here is a sample:
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>(); //initialize here
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
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);
}
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.RED);
}
// Drawing polyline in the Google Map for the i-th route
mMap.addPolyline(lineOptions);
}
}
For detail implementation Go through This Link
Related
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
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'm having performance issues adding polylines and thought that maybe it'll be possible to add them in a separate class extending AsyncTask. However as i learned that UI elements can't be added in such way (and polylines are UI elements).
Why i'm having performance issues while drawing polylines? Well, my polylines are drawn not from pos A to pos B but from my current location to destination (which is hardcoded for the sake of application atm). So the polylines are drawn when onLocationChange listener is executed and thus my application requires lots of proccessing power.
Any ideas how to use AsyncTask on this occasion?
This is the main class:
mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location arg0) {
// Get positions!
currentPOS = new LatLng(arg0.getLatitude(), arg0.getLongitude());
LatLng dst = new LatLng(58.378249, 26.714673);
CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(currentPOS, 13);
mMap.animateCamera(yourLocation);
mMap.addMarker(new MarkerOptions().position(dst).title("SCHOOL!"));
/*
// Remove comments to add marker to Liivi 2!
mMap.addMaker(new MarkerOptions().position(currentPOS).title("My POS"));
*/
if (currentPOS != null) {
//This is supposed to show directions
DirectionAPI directionAPI = new DirectionAPI(currentPOS, dst);
GoogleResponse googleResponse = null;
try {
googleResponse = (GoogleResponse) directionAPI.execute().get();
} catch (InterruptedException e) {
Log.e("CATCH","INTERRUPDED");
e.printStackTrace();
} catch (ExecutionException e) {
Log.e("CATCH","EXECUTIONEXCEPTION");
e.printStackTrace();
}
if (googleResponse.isOk()){
DrivingDirection drivingDirection = new DrivingDirection(googleResponse.getJsonObject());
polyline = drivingDirection.getTotalPolyline();
new drawPath(mMap,polyline).execute();
}
}
}
});
This is the Async for path drawing (which will result in an error due to UI conflict):
import android.graphics.Color;
import android.os.AsyncTask;
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 java.util.ArrayList;
/**
* Created by Kevin on 7.10.2015.
*/
public class drawPath extends AsyncTask{
private static ArrayList<LatLng> polyline;
private static GoogleMap mMap;
public drawPath(GoogleMap map, ArrayList<LatLng> polyline){
this.mMap = map;
this.polyline = polyline;
}
#Override
protected Object doInBackground(Object[] params) {
for (int i = 0; i < polyline.size() - 1; i++) {
LatLng src = polyline.get(i);
LatLng dest = polyline.get(i + 1);
// mMap is the Map Object
Polyline line = mMap.addPolyline(
new PolylineOptions().add(
new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude,dest.longitude)
).width(2).color(Color.BLUE).geodesic(true)
);
}
return null;
}
}
I solved this issue in a way that i did not add every polyline map separately but whole polyline. For example, before i had my location about 4km away from destination and it had 280 polylines between. On every onLocationChange these polylines were drawn one-by-one to map. Now they're all added at once - AsyncTask will create polylines in the background and in the post-execute they will be added.
#Override
protected Object doInBackground(Object[] params) {
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < polyline.size(); z++) {
LatLng point = polyline.get(z);
options.add(point);
}
return options;
}
protected void onPostExecute(Object result) {
Polyline line = mMap.addPolyline((PolylineOptions) result);
}
you can use this code
ublic class DrawrootTask extends AsyncTask<String, String, String> {
private Context context;
public static boolean flagCompleted = false;
private GoogleMap googleMap;
private double source_lat = 0.0;
private double source_long = 0.0;
private double dest_lat = 0.0;
private double dest_long = 0.0;
Userdata userdata;
String tag = "DrawRootTask";
private ProgressDialog progressDialog;
public static double dist, time;
private Polyline line;
String distanceText = "";
String durationText = "";
public DrawrootTask(Context context, LatLng source, LatLng destination,
GoogleMap googleMap) {
source_lat = source.latitude;
source_long = source.longitude;
dest_lat = destination.latitude;
dest_long = destination.longitude;
this.googleMap = googleMap;
this.context = context;
userdata = Userdata.getinstance(context);
}
protected void onPreExecute() {
// // TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(context.getResources().getString(
R.string.please_wait));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
String json = "";
// constructor
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
HashMap<String, String> keyValue = new HashMap<String, String>();
urlString.append("?origin=");// from
urlString.append(Double.toString(source_lat));
urlString.append(",");
urlString.append(Double.toString(source_long));
urlString.append("&destination=");// to
urlString.append(Double.toString(dest_lat));
urlString.append(",");
urlString.append(Double.toString(dest_long));
urlString.append("&sensor=false&mode=driving&alternatives=true");
// defaultHttpClient
String url = urlString.toString();
FetchUrl fetchurl = new FetchUrl();
json = fetchurl.fetchUrl(url, keyValue);
Log.e("Buffer Error", json);
return json;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
try {
progressDialog.dismiss();
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<LatLng> list = decodePoly(encodedString);
for (int z = 0; z < list.size() - 1; z++) {
LatLng src = list.get(z);
LatLng dest = list.get(z + 1);
line = googleMap.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
// .width(8).color(Color.BLUE).geodesic(true));
.width(8)
.color(context.getResources().getColor(
R.color.actionbar_color)).geodesic(true));
Log.i("draw root", "" + "" + line.toString());
}
JSONArray legs = routes.getJSONArray("legs");
JSONObject steps = legs.getJSONObject(0);
JSONObject duration = steps.getJSONObject("duration");
JSONObject distance = steps.getJSONObject("distance");
distanceText = distance.getString("text");
durationText = duration.getString("text");
Log.i("draw root", "" + distance.toString());
dist = Double.parseDouble(distance.getString("text").replaceAll(
"[^\\.0123456789]", ""));
time = Double.parseDouble(duration.getString("text").replaceAll(
"[^\\.0123456789]", ""));
userdata.setDistance(distanceText);
userdata.setTime(durationText);
Log.d(tag, "distace is " + dist + " time is " + time);
flagCompleted = true;
} catch (JSONException e) {
Log.d("draw root", "" + e);
}
}
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;
}
}
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.
I have app which set multiple routes on the map.
The problem is when I put two points in the map, he get the suggested routes but with one extra straight line.
I found a solution. I just get the main tag for polyline - overview_polyline
In the code are the new changes :)
pic multiple routes - alternatives=true - I set just one road
pic - if I set alternatives=false in xml link, the straight line disappears.
In the xml everything is fine.
I looked in to the 2 xml files with alternatives=false and alternatives=true but there are identical.
link to XML file
Thanks in advance.
this code display the information:
//Polyline
private class GetRouteTask extends AsyncTask<String, Void, String> {
String response = "";
#Override
protected String doInBackground(String... urls) {
//Get All Route values
v2GetRouteDirection = new GMapV2Direction();
document = v2GetRouteDirection.getDocument(latLngFrom, latLngTo, GMapV2Direction.MODE_DRIVING);
response = "Success";
return response;
}
#Override
protected void onPostExecute(String result) {
if(document != null){
ArrayList<LatLng> directionPoint = v2GetRouteDirection.getDirection(document);
PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);
for (int i = 0; i < directionPoint.size(); i++) {
rectLine.add(directionPoint.get(i));
}
// Adding route on the map
map.addPolyline(rectLine);
}
}
}
this code get the tag information:
public class GMapV2Direction {
public GMapV2Direction(){}
public final static String MODE_DRIVING = "driving";
public final static String MODE_WALKING = "walking";
public static String error = null;
public Document getDocument(LatLng start, LatLng end, String mode) {
String url = "http://maps.googleapis.com/maps/api/directions/xml?"
+ "origin=" + start.latitude + "," + start.longitude
+ "&destination=" + end.latitude + "," + end.longitude
+ "&sensor=false&units=metric&mode=driving&alternatives=true";
////////////////
//Set TimeOuts
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
try {
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet, localContext);
InputStream in = response.getEntity().getContent();
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(in);
return doc;
}
catch (ClientProtocolException e) {
error = "some";
e.printStackTrace();
} catch (IOException e) {
error = "some";
e.printStackTrace();
}
catch (Exception e) {
error = "some";
e.printStackTrace();
}
return null;
}
public ArrayList<LatLng> getDirection (Document doc) {
NodeList error = doc.getElementsByTagName("status");
int p;
Node error1 = null;
//взема последнич елемент на таг
for(p = 0;p<error.getLength();p++){
error1 = error.item(p);
}
if(p==p){
p--;
}
LatLng latLngZero = new LatLng(0.0, 0.0);
ArrayList<LatLng> list = new ArrayList<LatLng>();
list.add(latLngZero);
ArrayList<LatLng> listGeopoints = null;
if(error1.getFirstChild().getTextContent().equals("OK")) {
//new
NodeList routeTag,nl3;
listGeopoints = new ArrayList<LatLng>();
//get tag route
routeTag = doc.getElementsByTagName("route");
if (routeTag.getLength() > 0) {
//get first eelemnt of route
Element routeElement = (Element) routeTag.item(0);
//get tag overview_polyline
NodeList polylineList = routeElement.getElementsByTagName("overview_polyline");
Node node1 = polylineList.item(0);
nl3 = node1.getChildNodes();
Node latNode = nl3.item(getNodeIndex(nl3, "points"));
List<LatLng> arr = decodePoly(latNode.getTextContent());
for (int j = 0; j < arr.size(); j++) {
listGeopoints.add(new LatLng(arr.get(j).latitude, arr.get(j).longitude));
}
}
}
//////////////
else{
return list;
}
return listGeopoints;
}
private int getNodeIndex(NodeList nl, String nodename) {
for(int i = 0 ; i < nl.getLength() ; i++) {
if(nl.item(i).getNodeName().equals(nodename))
return i;
}
return -1;
}
private ArrayList<LatLng> decodePoly(String encoded) {
ArrayList<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 position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
poly.add(position);
}
return poly;
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
public class DirectionsJSONParser {
public List<List<List<HashMap<String,String>>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
List<List<List<HashMap<String,String>>>> routes1 = new ArrayList<List<List<HashMap<String,String>>>>() ;
JSONArray jRoutes = null;
JSONArray jLegs = 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>>();
List path1 = new ArrayList<ArrayList<HashMap<String,String>>>();
// Log.d("legs",jLegs.toString());
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
HashMap<String, String> hm1 = new HashMap<String, String>();
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
// Log.d("steps",jSteps.toString());
/** 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);
// Log.d("polyline",polyline.toString());
/** 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);
// Log.d("lat", Double.toString(((LatLng)list.get(l)).latitude));
// Log.d("lng", Double.toString(((LatLng)list.get(l)).longitude));
}
}
path1.add(path);
}
routes1.add(path1);
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes1;
}
/**
* 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;
}
}
Faced similar problem and soled it by using addall() method for polylineoptions object to draw line on map directly using array list of latlng's.
Cannot confirm but trying this code might help
Polyline
private class GetRouteTask extends AsyncTask<String, Void, String> {
String response = "";
#Override
protected String doInBackground(String... urls) {
//Get All Route values
v2GetRouteDirection = new GMapV2Direction();
document = v2GetRouteDirection.getDocument(latLngFrom, latLngTo, GMapV2Direction.MODE_DRIVING);
response = "Success";
return response;
}
#Override
protected void onPostExecute(String result) {
if(document != null){
ArrayList<LatLng> directionPoint = v2GetRouteDirection.getDirection(document);
PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);
rectLine.addall(directionPoint);
// Adding route on the map
map.addPolyline(rectLine);
}
}
}
LatLng origin = new latlng(type your starting point latitude and longtitude);
LatLng dest = new latlng(type your ending point latitude and longtitude);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
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&alternatives=true&units=metric&mode=driving";
//&alternatives=true&units=metric&mode=driving
// 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;
}
/**
* A method to download json data from 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;
}
// Fetches data from url passed
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);
}
}
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends AsyncTask<String, Integer, List<List<List<HashMap<String, String>>>>> {
// Parsing the data in non-ui thread
#Override
protected List<List<List<HashMap<String, String>>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<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<List<HashMap<String, String>>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = new PolylineOptions();
PolylineOptions lineOptions1 = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
Log.d("resultsize", result.size() + "");
int i = 0;
while (i < result.size()) {
// for(int i=0;i<result.size();i++){
//result.size()
//int g= i-1;
points = new ArrayList<LatLng>();
// lineOptions = new PolylineOptions();
// if(i==1){
// }else{
List<List<HashMap<String, String>>> path1 = result.get(i);
for (int s = 0; s < path1.size(); s++) {
Log.d("pathsize1", path1.size() + "");
// Fetching i-th route
List<HashMap<String, String>> path = path1.get(s);
Log.d("pathsize", path.size() + "");
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
lineOptions1 = new PolylineOptions();
HashMap<String, String> point = path.get(j);
// points = new ArrayList<LatLng>();
// 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);
// Log.d("latlng", position.toString());
points.add(position);
}
// lineOptions.addAll(points);
// lineOptions.width(5);
// lineOptions.color(Color.BLUE);
// map.addPolyline(lineOptions);
}
// }
if (i == 0) {
PolylineOptions line1 = new PolylineOptions();
line1.addAll(points);
line1.width(5);
line1.color(Color.RED);
map.addPolyline(line1);
} else if (i == 1) {
PolylineOptions line2 = new PolylineOptions();
line2.addAll(points);
line2.width(5);
line2.color(Color.BLUE);
map.addPolyline(line2);
} else if (i == 2) {
PolylineOptions line3 = new PolylineOptions();
line3.addAll(points);
line3.width(5);
line3.color(Color.GREEN);
map.addPolyline(line3);
}
// Adding all the points in the route to LineOptions
i++;
//
}
// Drawing polyline in the Google Map for the i-th route
// map.addPolyline(lineOptions);
}
}