Hi all…
Yet another post on Google Maps..
In this demo I will show you how to show a route between two places in Google Maps V2.
Hope you have gone through my previous posts before.
If not please check here.
You need to set up Maps Correctly for it to load.
Lets start by adding Markers on Tap on the Map.
Below is the Activity that adds the Map and sets a Click Listener for the Map.
MapsActivity.java
import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolylineOptions; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, Listener { private GoogleMap mMap; CameraUpdate cup; ArrayList<LatLng> markerPoints; public static final String TAG = "MAP DEMO"; public static final float DEFAULT_ZOOM_LEVEL = 9.0f; ArrayList<LatLng> points = null; PolylineOptions lineOptions = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); markerPoints = new ArrayList<LatLng>(); // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; //Moving to a sample location mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.5, -122.0), DEFAULT_ZOOM_LEVEL)); // Setting onclick event listener for the map mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng point) { // Already two locations if (markerPoints.size() > 1) { markerPoints.clear(); mMap.clear(); } // Adding new point to the ArrayList markerPoints.add(point); // Creating MarkerOptions MarkerOptions options = new MarkerOptions(); // Setting the position of the marker options.position(point); /** * For the start location, Marker color is GREEN, * for the end location, Marker color is MAGENTA. */ if (markerPoints.size() == 1) { options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); } else if (markerPoints.size() == 2) { options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); } // Checks, whether start and end locations are captured if (markerPoints.size() >= 2) { LatLng origin = markerPoints.get(0); LatLng dest = markerPoints.get(1); // Getting URL to the Google Directions API String url = GetDataFromUrl.getDirectionsUrl(origin, dest); GetDirections getDirections = new GetDirections(MapsActivity.this); getDirections.startGettingDirections(url); } // Add new marker to the Google Map Android API V2 mMap.addMarker(options); } }); } //The task for getting directions ends up here... @Override public void onSuccessfullRouteFetch(final List<List<HashMap<String, String>>> result) { //if it takes a long time, we will do it in a seperate thread... new Thread(new Runnable() { @Override public void run() { MarkerOptions markerOptions = new MarkerOptions(); // Traversing through all the routes for (List<HashMap<String, String>> path : result) { points = new ArrayList<LatLng>(); lineOptions = new PolylineOptions(); int size = path.size(); // Get all the points for this route for (HashMap<String, String> point : path) { 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(12); lineOptions.color(Color.RED); } //Do all UI operations on the UI thread only... runOnUiThread(new Runnable() { @Override public void run() { // Drawing polyline in the Google Map for the this route mMap.addPolyline(lineOptions); } }); } }).start(); } @Override public void onFail() { Log.i(TAG, "Failed to get directions from Google..."); } }
GetDataFromUrl.java
[This file gets the JSON Data as a String from the Google WebService]
import android.util.Log; import com.google.android.gms.maps.model.LatLng; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class GetDataFromUrl { public static 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; } /** A method to download json data from url */ public static String getDataFromUrl(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("Maps", "Exception while downloading url" + e.toString()); }finally{ iStream.close(); urlConnection.disconnect(); } return data; } }
GetDirections.java
Gets the data from the Google WebService and parses to Get the routes..
import android.os.AsyncTask; import android.util.Log; import org.json.JSONObject; import java.util.HashMap; import java.util.List; public class GetDirections { Listener listener; public GetDirections(Listener listener) { this.listener = listener; } public void startGettingDirections(String downloadUrl) { new DirectionsTask().execute(downloadUrl); } class DirectionsTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... url) { String data = null; try { // Fetching the data from Google Service data = GetDataFromUrl.getDataFromUrl(url[0]); } catch (Exception e) { Log.d("Background Task", e.toString()); } return data; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); ParserTask parserTask = new ParserTask(); // Parse JSON data received from Google parserTask.execute(result); } } /** * 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]); RoutesJsonParser parser = new RoutesJsonParser(); // Starts parsing data routes = parser.parse(jObject); } catch (Exception e) { listener.onFail(); e.printStackTrace(); } return routes; } // Executes in UI thread, after the parsing process @Override protected void onPostExecute(List<List<HashMap<String, String>>> result) { super.onPostExecute(result); if (result != null && result.size() > 0) listener.onSuccessfullRouteFetch(result); else listener.onFail(); } } }
RoutesJsonParser.java
Parses the data and get the Points to Plot on the Google Maps.
import com.google.android.gms.maps.model.LatLng; 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 RoutesJsonParser { /** * 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<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; } }
You can download the Complete Android Studio Source Code from here..…
Send your comments on coderzheaven@gmail.com.
Cant see a directional path.
instead a straight line is seen .
Please help me out with this issue.
Have the exact same code as mentioned above
Please try to use long distance routes.
Tried it but still showing a straight line
below mentioned are the locations that ive used.
I also have mailed you regarding the same issue.
Location one :
Latitude = 19.1026931 Longitude = 72.8861508
Location Two :
Latitude = 19.0866 Longitude = 72.9080
can you please tell me how to set a one marker in current location and 2nd one at at any position and i want to my route come on clicking on one button that is top on the map.