I marked 10 locations using Google Maps addMarker() and is that possible to show route for reach all locations, the shortest route to cover all locations. If we click on one location it shows a route to reach there but I need connected route not only for one at a time.
You can use Google Maps Directions API with up to 23 waypoints (excluding the origin and destination) (its enough for your 10 marker places) with optimize:true (from Official Docs Optimize your waypoints section):
you may pass optimize:true as the first argument within the waypoints
parameter to allow the Directions service to optimize the provided
route by rearranging the waypoints in a more efficient order.
Something like that request:
https://maps.googleapis.com/maps/api/directions/json?origin=kilimanoor,in&destination=delhi,in&waypoints=optimize:true|via:12.972614,77.619728|via:17.381196,78.491409|via:21.150758,79.090297&key=YOUR_API_KEY
And than you should parse JSON response and, for example, draw route polyline based on it (you need data from overview_polyline tag for that). You can use code like this:
private String buildDirectionsUrl(List<LatLng> trackPoints) {
if (trackPoints.size() < 2) {
return null;
}
final LatLng origin = trackPoints.get(0);
final LatLng dest = trackPoints.get(trackPoints.size() - 1);
StringBuilder url = new StringBuilder();
url.append("https://maps.googleapis.com/maps/api/directions/json?");
url.append(String.format("origin=%8.5f,%8.5f", origin.latitude, origin.longitude));
url.append(String.format("&destination=%8.5f,%8.5f", dest.latitude, dest.longitude));
// add waypoints, if they exists
if (trackPoints.size() > 2) {
url.append("&waypoints=optimize:true|");
LatLng wayPoint;
for (int ixWaypoint = 1; ixWaypoint < trackPoints.size() - 2; ixWaypoint++) {
wayPoint = trackPoints.get(ixWaypoint);
url.append(String.format("%8.5f,%8.5f|", wayPoint.latitude, wayPoint.longitude));
}
url.delete(url.length() - 1, url.length());
}
url.append(String.format("&key=%s", getResources().getString(R.string.google_maps_key)));
return url.toString();
}
private class GetDirectionPointsAsyncTask extends AsyncTask<List<LatLng>, Void, List<LatLng>> {
protected void onPreExecute() {
super.onPreExecute();
}
protected List<LatLng> doInBackground(List<LatLng>... params) {
List<LatLng> routePoints = new ArrayList<>();
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(buildDirectionsUrl(params[0]));
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder jsonStringBuilder = new StringBuilder();
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
jsonStringBuilder.append(line);
jsonStringBuilder.append("\n");
}
JSONObject jsonRoot = new JSONObject(jsonStringBuilder.toString());
JSONArray jsonRoutes = jsonRoot.getJSONArray("routes");
if (jsonRoutes.length() < 1) {
return null;
}
JSONObject jsonRoute = jsonRoutes.getJSONObject(0);
JSONObject overviewPolyline = jsonRoute.getJSONObject("overview_polyline");
String overviewPolylineEncodedPoints = overviewPolyline.getString("points");
routePoints = decodePoly(overviewPolylineEncodedPoints);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return routePoints;
}
#Override
protected void onPostExecute(List<LatLng> result) {
super.onPostExecute(result);
PolylineOptions polyLineOptions = new PolylineOptions();
polyLineOptions.addAll(result);
polyLineOptions.width(5);
polyLineOptions.color(Color.RED);
mGoogleMap.addPolyline(polyLineOptions);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(result.get(0));
builder.include(result.get(result.size()-1));
LatLngBounds bounds = builder.build();
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));
}
}
//
// 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<>();
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;
}
Also see this tutorial.
Related
I wanted to add some checkpoints(Marker) into Google map between the Source and destination as per available route in my Android App.
Check this Google Maps tutorial HERE.
On the step 4, you parse a JSON which contains the different routes. From each route you can get the points with Lat and Lng values.
public class PathToDestination {
private GoogleMap mMap;
private Context context;
private static final String API_KEY = "your key";
private String pathColor = "#05b1fb";//default blue color
private int pathWidth = 5;//default is 5
private Polyline line;
private PolylineOptions polylineOptions;
public PathToDestination(Context context, GoogleMap mMap) {
this.context = context;
this.mMap = mMap;
}
public void setPathColor(String pathColor) {
this.pathColor = pathColor;
}
public void setPathWidth(int pathWidth) {
this.pathWidth = pathWidth;
}
public void drawPathBetween(#MapManager.PathMode int mode, double sourcelat, double sourcelog, double destlat, double destlog) {
drawPathBetween(mode, sourcelat, sourcelog, destlat, destlog, null);
}
public void drawPathBetween(#MapManager.PathMode int mode, double sourcelat, double sourcelog, double destlat, double destlog, MapModel[] waypoints) {
String urlStr = makeURL(mode, sourcelat, sourcelog, destlat, destlog, waypoints);
new ConnectAsyncTask(urlStr).execute();
}
/*private String makeURL(double sourcelat, double sourcelog, double destlat, double destlog) {
return makeURL(sourcelat, sourcelog, destlat, destlog, );
}*/
private String makeURL(#MapManager.PathMode int mode, double sourcelat, double sourcelog, double destlat, double destlog, MapModel... waypoints) {
StringBuilder urlString = new StringBuilder();
urlString.append("https://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin=");// from
urlString.append(Double.toString(sourcelat));
urlString.append(",");
urlString.append(Double.toString(sourcelog));
if (waypoints != null && waypoints.length > 0) {
urlString.append("&waypoints=");// waypoints
for (int i = 0; i < waypoints.length; i++) {
MapModel coordinate = waypoints[i];
urlString.append(coordinate.getLatitude());
urlString.append(",");
urlString.append(coordinate.getLongitude());
if (i < waypoints.length - 1) {
urlString.append("|");
}
}
}
urlString.append("&destination=");// to
urlString.append(Double.toString(destlat));
urlString.append(",");
urlString.append(Double.toString(destlog));
urlString.append("&sensor=false");
urlString.append("&mode=" + mode);
urlString.append("&alternatives=true");
urlString.append("&key=" + API_KEY);
return urlString.toString();
}
private void drawPath(String result) {
try {
//Tranform the string into a json object
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 = null;
if (polylineOptions == null) {
polylineOptions = new PolylineOptions()
.width(pathWidth)
.color(Color.parseColor(pathColor)) //Google maps blue color
.geodesic(true);
}
list = decodePoly(encodedString);
polylineOptions.addAll(list);
if (line == null) {
line = mMap.addPolyline(polylineOptions);
}
line.setPoints(list);
/*
for(int z = 0; z<list.size()-1;z++){
LatLng src= list.get(z);
LatLng dest= list.get(z+1);
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));
}
*/
} catch (JSONException e) {
e.printStackTrace();
}
}
public void drawPathFromEncodedPolyline(String encodedPolyline) {
// try {
//Tranform the string into a json object
// 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(encodedPolyline);
Polyline line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.width(5)
.color(Color.parseColor("#05b1fb"))//Google maps blue color
.geodesic(true)
);
/*
for(int z = 0; z<list.size()-1;z++){
LatLng src= list.get(z);
LatLng dest= list.get(z+1);
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));
}
*/
// } catch (JSONException e) {
// e.printStackTrace();
// }
}
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;
}
private class ConnectAsyncTask extends AsyncTask<Void, Void, String> {
private ProgressDialog progressDialog;
String url;
ConnectAsyncTask(String urlPass) {
url = urlPass;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 &&
!((Activity) context).isDestroyed()) ||
!((Activity) context).isFinishing()) {
progressDialog = new ProgressDialog(context);
// progressDialog.setMessage("Fetching route, Please wait...");
// progressDialog.setIndeterminate(true);
// progressDialog.show();
}
}
#Override
protected String doInBackground(Void... params) {
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
URL url = new URL(this.url);
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
return jsonResults.toString();
} catch (IOException e) {
return jsonResults.toString();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return jsonResults.toString();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (progressDialog != null) {
progressDialog.hide();
}
if (result != null) {
drawPath(result);
}
}
}
public void clearRoute() {
if (line != null) {
line.remove();
}
line = null;
polylineOptions = null;
}
}
Here MapModel is an interface
public interface MapModel {
double getLatitude();
double getLongitude();
}
If you want the list of LatLng you can easily get that from
drawPathFromEncodedPolyline(String encodedPolyline)
method.
You can look here for other map functions.
I am currently trying to draw routes between 2 destinations utilizing requested JSON data from Google's Directions API. The version I currently have works well with destinations within around 150 miles. Yet when I try drawing poly lines across a state the application crashes. Below is the snippet of my Async task.
public class FetchRouteStepsFromService extends AsyncTask<Void,Void,StringBuilder> {
private LocalBroadcastManager manager;
private String currentAddress;
private String destinationAddress;
public FetchRouteStepsFromService(String currentAddress, String destinationAddress, Context context){
this.currentAddress = currentAddress;
this.destinationAddress = destinationAddress;
manager = LocalBroadcastManager.getInstance(context);
}
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;
}
#Override
protected void onPostExecute(StringBuilder result) {
super.onPostExecute(result);
try{
JSONObject jsonObj = new JSONObject(result.toString());
JSONArray routesJSONArray = jsonObj.getJSONArray("routes");
JSONObject beforeLegsJSONObject = routesJSONArray.getJSONObject(0);
JSONArray legsJSONArray = beforeLegsJSONObject.getJSONArray("legs");
JSONObject beforeStepsJSONObject = legsJSONArray.getJSONObject(0);
JSONArray stepsJSONArray = beforeStepsJSONObject.getJSONArray("steps");
List<LatLng> test = new ArrayList<>();
ArrayList<PolylineOptions> options = new ArrayList<>();
map.clear();
for(int i = 0; i < stepsJSONArray.length(); i++){
JSONObject object = stepsJSONArray.getJSONObject(i);
JSONObject polyLineObject = object.getJSONObject("polyline");
String encodedPoly = polyLineObject.getString("points");//Holds the code for the polyline (String)
test = decodePoly(encodedPoly);
//Todo: Maybe create a separate asynctask to add latlngs on separate thread?
for(int j = 0; j < test.size();j++){
PolylineOptions options1;
if(j != test.size() -1) {
LatLng startLocation = test.get(j);
LatLng nextLocation = test.get(j + 1);
options1 = new PolylineOptions().add(startLocation, nextLocation).width(5).color(Color.GREEN).geodesic(true);
map.addPolyline(options1);
}else{
LatLng startLocation = test.get(j);
LatLng nextLocation = test.get(j);
options1 = new PolylineOptions().add(startLocation, nextLocation).width(5).color(Color.GREEN).geodesic(true);
map.addPolyline(options1);
}
}
}
dialog.dismiss();
updateUI();
}catch (Exception e){
e.printStackTrace();
}
}
#Override
protected StringBuilder doInBackground(Void... params) {
try{
StringBuilder jsonResults = new StringBuilder();
String googleMapUrl = "https://maps.googleapis.com/maps/api/directions/json?" +
"origin="+currentAddress+"&" +
"destination="+destinationAddress+"&key=MY_KEY";
URL url = new URL(googleMapUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
int read;
char[] buff = new char[3000];
while((read = in.read(buff,0,3000)) != -1 ){
jsonResults.append(buff,0,read);
}
return jsonResults;
}catch (Exception e){
Log.d("PlanTrip","doInBackgroud exception");
e.printStackTrace();
}
return null;
}
}
This is a local class within my Fragment which holds the Google Map. I previously have tried to make this AsyncTask its own class. This class would broadcast an intent consisting of PolyLineOptions which would be received by the fragment's BroadcastReceiver. Although this did not work either. Any resources, advice, or feedback would be greatly appreciated.
EDIT 1: Logcat during large request
Here is my code :
public class MyGoogleMapActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.googlemap);
GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
LatLng Paris= new LatLng(64.711696, 12.170481);
map.addMarker(new MarkerOptions().title("LolluSaba").position(Paris));
LatLng Cinema= new LatLng(34.711696, 2.170481);
map.addMarker(new MarkerOptions().title("Pseudo").position(Cinema));
}
}
And i like to draw a route from Paris to Cinema. How can I do it very simply ?
Assuming that you have the coordinates of the two points you want to draw, you can get the route from google using the following methods:
class GetDirection extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MapaAnunciante.this);
dialog.setMessage("Drawing the route, please wait!");
dialog.setIndeterminate(false);
dialog.setCancelable(false);
dialog.show();
}
protected String doInBackground(String... args) {
String stringUrl = "http://maps.googleapis.com/maps/api/directions/json?origin=" + origin+ "&destination=" + destination+ "&sensor=false";
StringBuilder response = new StringBuilder();
try {
URL url = new URL(stringUrl);
HttpURLConnection httpconn = (HttpURLConnection) url
.openConnection();
if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader input = new BufferedReader(
new InputStreamReader(httpconn.getInputStream()),
8192);
String strLine = null;
while ((strLine = input.readLine()) != null) {
response.append(strLine);
}
input.close();
}
String jsonOutput = response.toString();
JSONObject jsonObject = new JSONObject(jsonOutput);
// routesArray contains ALL routes
JSONArray routesArray = jsonObject.getJSONArray("routes");
// Grab the first route
JSONObject route = routesArray.getJSONObject(0);
JSONObject poly = route.getJSONObject("overview_polyline");
String polyline = poly.getString("points");
pontos = decodePoly(polyline);
} catch (Exception e) {
}
return null;
}
protected void onPostExecute(String file_url) {
for (int i = 0; i < pontos.size() - 1; i++) {
LatLng src = pontos.get(i);
LatLng dest = pontos.get(i + 1);
try{
//here is where it will draw the polyline in your map
Polyline line = map.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
.width(2).color(Color.RED).geodesic(true));
}catch(NullPointerException e){
Log.e("Error", "NullPointerException onPostExecute: " + e.toString());
}catch (Exception e2) {
Log.e("Error", "Exception onPostExecute: " + e2.toString());
}
}
dialog.dismiss();
}
}
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;
}
Where origin and destination are two strings containing the lat and lng of the points, formatted like "-1.0,2.0":
String origin = "64.711696,12.170481";
String destination = "34.711696,2.170481";
To execute it, just call new GetDirection().execute();
Hope it helps!
As you have two points so send it through google json which provides to draw route
between two points. See this example.
Route direction between two location
You Need to use the Directions API in combination with the Android Maps util Lib
Get the Encoded Polyline String from the Directions Api.
Decode the encoded string using Maps Util Lib into a list of lat/lng's (https://developers.google.com/maps/documentation/android/utility/#poly-encoding)
Draw the Polyline on the map using the lat/lngs!
First a List of LatLng you need
List<LatLng> ls_pos=new ArrayList<>();
After that In OnMapReady
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker) {
if (ls_pos.size() >= 2) {
mMap.addPolyline(newPolylineOptions().addAll(ls_pos).width(10).color(Color.RED).visible(true).clickable(true));
ls_pos.clear
That's Work for me.
im working with google maps API to route between some points (asking google apis for those road paths)..
in majority process working good but sometime got a JSONException: Index 0 out of range [0..0) while trying getJSONObject(0) on JSONArray("routes") cousing my app loss some road path;
im using real device with WiFi connection when testing this app, I think this it not the problem..
here some of my stuff..
on Asynctask
protected void onProgressUpdate(String... progress) {
super.onProgressUpdate();
if (progress != null)
drawPath(progress[0],color);
}
#Override
protected String doInBackground(Void... params) {
for (int i = 0; i < route_.size() - 1; i++) {
String url = jsonParser.makeURL(route_.get(i).latitude,
route_.get(i).longitude, route_.get(i + 1).latitude,
route_.get(i + 1).longitude);
//Log.i(TAG, i +" Asynctask : " + url);
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
publishProgress(json);
}
return "";
}
URL maker
public String makeURL(double sourcelat, double sourcelog, double destlat,
double destlog) {
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin=");// from
urlString.append(Double.toString(sourcelat));
urlString.append(",");
urlString.append(Double.toString(sourcelog));
urlString.append("&destination=");// to
urlString.append(Double.toString(destlat));
urlString.append(",");
urlString.append(Double.toString(destlog));
urlString.append("&sensor=false&mode=driving&alternatives=false"); //Log.d(TAG, urlString.toString());
return urlString.toString();
}
getting JSON form URL
public String getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
json = sb.toString();
is.close();
} catch (Exception e) {
Log.e(TAG, "Buffer Error converting result " + e.toString());
}
return json;
}
public 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(((lat / 1E5)), ((lng / 1E5)));
poly.add(p);
}
return poly;
}
Drawing path
public void drawPath(String result , int color) {
try {
final JSONObject json = new JSONObject(result);
calcuDistTime(json);
JSONArray routeArray = json.getJSONArray("routes");Log.d(TAG, "JSON Len " + routeArray.length());
JSONObject routes;
routes = routeArray.getJSONObject(0); <<< HERE THE PROBLEM org.json.JSONException: Index 0 out of range [0..0)
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<LatLng> list = jsonParser.decodePoly(encodedString);
for (int z = 0; z < list.size() - 1; z++) {
LatLng src = list.get(z);
LatLng dest = list.get(z + 1);
map.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
.width(8).color(color).geodesic(true));
// Log.d(TAG, z + "DRAW POLYLINE : " + list.get(z).toString());
}
} catch (JSONException e) {
Log.w(TAG, e.toString());
}
}
failed when routeArray.getJSONObject(0) got JSONException: Index 0 out of range [0..0) cousing my app loss some paths like above..
please help me which one I must change :(
thanks,
My Best Regards..
EDIT : after printing my JSONObject the problem is {"status":"OVER_QUERY_LIMIT","routes":[]}..this is why my problem like randomly .so sad :(..
how to solve that?
any tricks?.
I'm trying to create an Android application that takes in an origin and destination and works along the lines of a GPS.
I was wondering if it was possible (through Google APIs) to display a map that shows the path between point A and B but also shows your current location on top of that path using GPS. I have seen tutorials and articles on how to display just the path between two points using Google directions and maps API but not combining that with your current location dot.
I have not really started this project yet because I am trying to figure out how to best approach this. Any help, tutorials, examples, suggestions will be appreciated!
You must get the your current latitude and longitude first. You can check the link for the same in the below link
http://developer.android.com/guide/topics/location/strategies.html
You must fetch the latitude and longitudes between source and destination. Which should be done using asynctask.
new connectAsyncTask().execute()
The asynctask class
private class connectAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
fetchData();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(doc!=null){
NodeList _nodelist = doc.getElementsByTagName("status");
Node node1 = _nodelist.item(0);
String _status1 = node1.getChildNodes().item(0).getNodeValue();
if(_status1.equalsIgnoreCase("OK")){
Toast.makeText(MainActivity.this,"OK" , 1000).show();
NodeList _nodelist_path = doc.getElementsByTagName("overview_polyline");
Node node_path = _nodelist_path.item(0);
Element _status_path = (Element)node_path;
NodeList _nodelist_destination_path = _status_path.getElementsByTagName("points");
Node _nodelist_dest = _nodelist_destination_path.item(0);
String _path = _nodelist_dest.getChildNodes().item(0).getNodeValue();
List<LatLng> points = decodePoly(_path);
for (int i = 0; i < points.size() - 1; i++) {
LatLng src = points.get(i);
LatLng dest = points.get(i + 1);
// Polyline to display the routes
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))
}
progressDialog.dismiss();
}else{
// Unable to find route
}
}else{
// Unable to find route
}
}
}
DecodePoly function
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;
}
Fetch data
Here flati and flongi is the source latitude and longitude
dlati and dlongi is the destination latitude and longitude
Document doc = null;
private void fetchData()
{
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps/api/directions/xml?origin=");
urlString.append( Double.toString(flati));
urlString.append(",");
urlString.append( Double.toString(flongi));
urlString.append("&destination=");//to
urlString.append( Double.toString(dlati));
urlString.append(",");
urlString.append( Double.toString(dlongi));
urlString.append("&sensor=true&mode=walking");
Log.d("url","::"+urlString.toString());
HttpURLConnection urlConnection= null;
URL url = null;
try
{
url = new URL(urlString.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = (Document) db.parse(urlConnection.getInputStream());//Util.XMLfromString(response);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}catch (ParserConfigurationException e){
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You can get an idea on how to implement Google Map API V2 in your application by reading this guide I wrote on this topic:
Google Map API V2
Then you could implement the driving navigation root using this answer I gave here:
Draw driving route between 2 GeoPoints on GoogleMap SupportMapFragment
and to find your current location you should implement a loicationListener, you can see an example here:
http://about-android.blogspot.co.il/2010/04/find-current-location-in-android-gps.html