I have an app that find the shortest distance between my user to a polygon.
I want to convert the polygon to Geofence to check the distance between the user to the area to give mor accurate information to the user.
how can I do that?
this is the MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, MinimumDistanceTask.GetMinimumDistanceListener {
private GoogleMap mMap;
private LocationManager manager;
private double lat, lng;
private KmlLayer layer;
private LatLng latLngTest;
private boolean contains = false;
private ArrayList<LatLng> outerBoundary;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// 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);
manager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
String provider = LocationManager.GPS_PROVIDER;
//take the user location every second
try {
manager.requestLocationUpdates(provider, 1000, 0, this);
}catch (SecurityException e){
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onLocationChanged(Location location) {
//clear map before create new location
mMap.clear();
try {
//load the kml file
layer = new KmlLayer(mMap, R.raw.polygon_layer, this);
layer.addLayerToMap();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
lat = location.getLatitude();
lng = location.getLongitude();
latLngTest = new LatLng(lat,lng);
// Add a marker in user location
LatLng userLocation = new LatLng(latLngTest.latitude, latLngTest.longitude);
mMap.addMarker(new MarkerOptions().position(userLocation).title("you are here"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
//check if the user in the polygon
boolean inside = ifUserInside();
if(inside){
Toast.makeText(MapsActivity.this, "you are in the polygon", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MapsActivity.this, "you are outside the polygon", Toast.LENGTH_SHORT).show();
//create the string address for the url
String address = "";
for (int i = 0; i < outerBoundary.size(); i++) {
address += (outerBoundary.get(i).toString() + "|");
address = address.replace("lat/lng:", "");
address = address.replace(" ", "");
address = address.replace("(", "");
address = address.replace(")", "");
}
MinimumDistanceTask task = new MinimumDistanceTask(this);
task.execute("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+latLngTest.latitude+ "," + latLngTest.longitude
+ "&destinations=" + address + "&mode=walking");
}
}
#Override
public void getMinimumDistance(int closeLocation) {
//check if you get results properly
if(closeLocation != -1) {
GetDirection direction = new GetDirection();
direction.execute("https://maps.googleapis.com/maps/api/directions/json?origin=" + latLngTest.latitude + "," + latLngTest.longitude
+ "&destination=" + outerBoundary.get(closeLocation).latitude + "+" + outerBoundary.get(closeLocation).longitude);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public boolean ifUserInside(){
if (layer.getContainers() != null) {
for (KmlContainer container : layer.getContainers()) {
if (container.getPlacemarks() != null) {
for (KmlPlacemark placemark : container.getPlacemarks()) {
contains = false;
if (placemark.getGeometry() instanceof KmlPolygon) {
KmlPolygon polygon = (KmlPolygon) placemark.getGeometry();
// Get the outer boundary and check if the test location lies inside
outerBoundary = polygon.getOuterBoundaryCoordinates();
contains = PolyUtil.containsLocation(latLngTest, outerBoundary, true);
if (contains) {
// Get the inner boundaries and check if the test location lies inside
ArrayList<ArrayList<LatLng>> innerBoundaries = polygon.getInnerBoundaryCoordinates();
if (innerBoundaries != null) {
for (ArrayList<LatLng> innerBoundary : innerBoundaries) {
// If the test location lies in a hole, the polygon doesn't contain the location
if (PolyUtil.containsLocation(latLngTest, innerBoundary, true)) {
contains = false;
}
}
}
}
}
}
}
}
}
return contains;
}
public class GetDirection extends AsyncTask<String , Void, String> {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
#Override
protected String doInBackground(String... params) {
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return "Error from server";
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
#Override
protected void onPostExecute(String s) {
//get the polyline string
String polygonPoints = "";
try {
JSONObject object = new JSONObject(s);
JSONArray array = object.getJSONArray("routes");
for (int i = 0; i < array.length(); i++) {
JSONObject arrObj1 = array.getJSONObject(i);
JSONObject points = arrObj1.getJSONObject("overview_polyline");
polygonPoints = points.getString("points");
}
//convert the string to polyline;
ArrayList<LatLng> a = new ArrayList<>(decodePolyPoints(polygonPoints));
//add polyline to the map
mMap.addPolyline(new PolylineOptions().addAll(a).width(10).color(Color.BLUE));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
//the method that convert the string to polyline
public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
int len = encodedPath.length();
final ArrayList<LatLng> path = new ArrayList<LatLng>();
int index = 0;
int lat = 0;
int lng = 0;
while (index < len) {
int result = 1;
int shift = 0;
int b;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
result = 1;
shift = 0;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
path.add(new LatLng(lat * 1e-5, lng * 1e-5));
}
return path;
}
}
This is my AsyncTask to get the minimum distance point
public class MinimumDistanceTask extends AsyncTask<String, Void, Integer>{
private int closeLocation;
// private String points;
private GetMinimumDistanceListener listener;
public MinimumDistanceTask(GetMinimumDistanceListener listener){
// this.points = points;
this.listener = listener;
}
#Override
protected Integer doInBackground(String... params) {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
int minimumDis = -1;
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return -1;
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
///get the json data
JSONObject jsonObject1 = new JSONObject(builder.toString());
JSONArray points = jsonObject1.getJSONArray("rows");
JSONObject jsonObject2 = points.getJSONObject(0);
JSONArray elements = jsonObject2.getJSONArray("elements");
for (int i = 0; i < elements.length(); i++) {
JSONObject jsonObject3 = elements.getJSONObject(i);
JSONObject distance = jsonObject3.getJSONObject("distance");
if( distance.getInt("value") < minimumDis || minimumDis == -1) {
minimumDis = distance.getInt("value");
closeLocation = i;
}
}
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return closeLocation;
}
#Override
protected void onPostExecute(Integer closeLocation) {
listener.getMinimumDistance(closeLocation);
}
public interface GetMinimumDistanceListener{
void getMinimumDistance(int closeLocation);
}
}
thanks a lot :)
You can use a function like the following to calculate the nearest point from polygon defined by a List<LatLng> and a given LatLng.
It uses the PolyUtil.distanceToLine from the Google Maps Android API Utility Library to compute the distance between the test LatLng and every segment of the list, and a method based on the distanceToLine method from https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java to compute the projection of a point on a segment.
private LatLng findNearestPoint(LatLng test, List<LatLng> target) {
double distance = -1;
LatLng minimumDistancePoint = test;
if (test == null || target == null) {
return minimumDistancePoint;
}
for (int i = 0; i < target.size(); i++) {
LatLng point = target.get(i);
int segmentPoint = i + 1;
if (segmentPoint >= target.size()) {
segmentPoint = 0;
}
double currentDistance = PolyUtil.distanceToLine(test, point, target.get(segmentPoint));
if (distance == -1 || currentDistance < distance) {
distance = currentDistance;
minimumDistancePoint = findNearestPoint(test, point, target.get(segmentPoint));
}
}
return minimumDistancePoint;
}
/**
* Based on `distanceToLine` method from
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java
*/
private LatLng findNearestPoint(final LatLng p, final LatLng start, final LatLng end) {
if (start.equals(end)) {
return start;
}
final double s0lat = Math.toRadians(p.latitude);
final double s0lng = Math.toRadians(p.longitude);
final double s1lat = Math.toRadians(start.latitude);
final double s1lng = Math.toRadians(start.longitude);
final double s2lat = Math.toRadians(end.latitude);
final double s2lng = Math.toRadians(end.longitude);
double s2s1lat = s2lat - s1lat;
double s2s1lng = s2lng - s1lng;
final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
/ (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
if (u <= 0) {
return start;
}
if (u >= 1) {
return end;
}
return new LatLng(start.latitude + (u * (end.latitude - start.latitude)),
start.longitude + (u * (end.longitude - start.longitude)));
}
You can test it with the following code:
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(2, 2));
points.add(new LatLng(4, 2));
points.add(new LatLng(4, 4));
points.add(new LatLng(2, 4));
points.add(new LatLng(2, 2));
LatLng testPoint = new LatLng(3, 0);
LatLng nearestPoint = findNearestPoint(testPoint, points);
Log.e("NEAREST POINT: ", "" + nearestPoint); // lat/lng: (3.0,2.0)
Log.e("DISTANCE: ", "" + SphericalUtil.computeDistanceBetween(testPoint, nearestPoint)); // 222085.35856591124
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 have a code in which i call function(getData) before map fragment so that function is executed from that i call showList function but this is executed only after the OnMapready function. I actually don't know the reason behind it. The system first said that more work is done in main thread so skipped 49 frames to clear this i executed Showlist even as async task but the map function is called before ShowList(). Anyone say me the reason behind it. I know some logic is there but don't know what it is?
my code
public class GetCo extends FragmentActivity implements OnMapReadyCallback {
String path1la, path1lo, path2la, path2lo;
double dsla, dslo, ddla, ddlo, dp1la, dp1lo, dp2la, dp2lo;
private GoogleMap mMap;
public String myJSON;
private static final String TAG_RESULT = "RESULT";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "Taskname";
private static final String TAG_KILOMETER = "Kilometer";
private static final String TAG_TIMING = "Timing";
private static final String TAG_SOLA = "SourceLa";
private static final String TAG_SOLO = "SourceLo";
private static final String TAG_DLA = "DestinationLa";
private static final String TAG_DLO = "DestinationLo";
private static final String TAG_P1LA = "Path1La";
private static final String TAG_P1LO = "Path1Lo";
private static final String TAG_P2LA = "Path2La";
private static final String TAG_P2LO = "Path2Lo";
JSONArray array = null;
String id, name, kmeter, time, sla, slo, p1la, p1lo, p2la, p2lo, dla, dlo;
TableLayout tl;
TableRow tr;
int c, vt;
TextView tn, kms, tm;
Button map;
String result=null;
String task;
#Override
public void onCreate(Bundle savedInstanceState) {
Intent in = getIntent();
task = in.getExtras().getString("task");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
getData();
// 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);
}
public void getData() {
class GetDataJSON extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("www.futuroitsolutions.in")
.appendPath("php_android_api")
.appendPath("datare.php")
.appendQueryParameter("Taskname", task);
String myUrl = builder.build().toString();
Log.d("String",task);
Log.d("url",myUrl);
HttpGet httpget = new HttpGet(myUrl);
// Depends on your web service
httpget.setHeader("Content-type", "application/json");
InputStream inputStream = null;
try {
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
// Oops
} finally {
try {
if (inputStream != null) inputStream.close();
} catch (Exception squish) {
}
}
return result;
}
#Override
protected void onPostExecute(String result) {
myJSON=result;
Log.d("jsooon",myJSON);
ShowList(myJSON);
}
}
GetDataJSON g = new GetDataJSON();
g.execute();
}
public void ShowList(String json) {
final String vi = json;
{
class GetData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
JSONObject j = null;
j = new JSONObject(vi);
// String notes = j.getString("result");
array = j.getJSONArray("result");
for (int i = 0; i < array.length(); i++) {
JSONObject c = array.getJSONObject(i);
id = c.getString(TAG_ID);
name = c.getString(TAG_NAME);
kmeter = c.getString(TAG_KILOMETER);
time = c.getString(TAG_TIMING);
sla = c.getString(TAG_SOLA);
slo = c.getString(TAG_SOLO);
p1la = c.getString(TAG_P1LA);
p1lo = c.getString(TAG_P1LO);
p2la = c.getString(TAG_P2LA);
p2lo = c.getString(TAG_P2LO);
dla = c.getString(TAG_DLA);
dlo = c.getString(TAG_DLO);
vt = array.length();
String v = String.valueOf(c);
String x = String.valueOf(vt);
Log.d("tagggggg", v);
Log.d("tag", name);
Log.d("tag", kmeter);
Log.d("tag", time);
Log.d("tag", x);
Log.d("lat", sla);
Log.d("log", slo);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
}
GetData g = new GetData();
g.execute();
}
}
public void onMapReady(GoogleMap googleMap) {
Log.d("start","first");
mMap = googleMap;
// dsla = Double.parseDouble(sla);
try {
// sla = URLEncoder.encode(sla, "UTF-8");
Log.d("inmap", sla);
dsla = Double.parseDouble(sla);
// slo = URLEncoder.encode(slo, "UTF-8");
dslo = Double.parseDouble(slo);
//path1la = URLEncoder.encode(path1la, "UTF-8");
dp1la = Double.parseDouble(path1la);
// path1lo = URLEncoder.encode(path1lo, "UTF-8");
dp1lo = Double.parseDouble(path1lo);
// path2la = URLEncoder.encode(path2la, "UTF-8");
dp2la = Double.parseDouble(path2la);
// path2lo = URLEncoder.encode(path2lo, "UTF-8");
dp2lo = Double.parseDouble(path2lo);
// dla = URLEncoder.encode(dla, "UTF-8");
ddla = Double.parseDouble(dla);
// dlo = URLEncoder.encode(dlo, "UTF-8");
ddlo = Double.parseDouble(dlo);
} catch (Exception e) {
}
String url1 = getMapsApiDirectionsUrl(dsla,dslo,dp1la,dp1lo,ddla,ddlo);
new connectAsyncTask(url1).execute();
// Getting JSON from URL
// Add a marker in Sydney and move the camera
LatLng kakkanad = new LatLng(10.007243, 76.354628);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(kakkanad, 18));
// mMap.addMarker(new MarkerOptions()
// .position(kakkanad)
// .title("Marker in kakkanad"));
//mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Source, 18));
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
}
public String getMapsApiDirectionsUrl(double dsla,double dslo,double dp1la,double dp2lo,double ddla,double ddlo) {
//Log.d("in func",sla);
String c=String.valueOf(dsla);
Log.d("in func",c);
final LatLng source = new LatLng(dsla, dslo);
final LatLng path1 = new LatLng(dp1la, dp2lo);
final LatLng path2 = new LatLng(dp2la, dp2lo);
final LatLng dest = new LatLng(ddla, ddlo);
String origin = "", waypoints = "", destination = "";
try {
origin = "origin=" + URLEncoder.encode(String.valueOf(source.latitude), "UTF-8") + "," + URLEncoder.encode(String.valueOf(source.longitude), "UTF-8");
waypoints = "waypoints=" + URLEncoder.encode(String.valueOf(path1.latitude), "UTF-8") + "," + URLEncoder.encode(String.valueOf(path1.longitude), "UTF-8");
destination = "destination=" + URLEncoder.encode(String.valueOf(dest.latitude), "UTF-8") + "," + URLEncoder.encode(String.valueOf(dest.longitude), "UTF-8");
} catch (UnsupportedEncodingException e) {
}
String way = "", sour = "", desty = "";
try {
way = URLEncoder.encode(waypoints, "UTF-8");
desty = URLEncoder.encode(destination, "UTF-8");
sour = URLEncoder.encode(origin, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
String key = "key=AIzaSyDOidVs6_dHl0cjEJ0-OhMfUY0oNFf1SOE";
String params = origin + "&" + destination + "&" + waypoints + "&" + key;
String output = "json";
// https://maps.googleapis.com/maps/api/directions/json?origin=Boston,MA&destination=Concord,MA&waypoints=Charlestown,MA|Lexington,MA&key=YOUR_API_KEY
// String url1="https://maps.googleapis.com/maps/api/directions/json?origin=edapally,kerala&destination=ernakulam,kerala&waypoints=optimize:true|palarivattom,kerala|vytilla,kerala&key=AIzaSyDOidVs6_dHl0cjEJ0-OhMfUY0oNFf1SOE";
String url = "https://maps.googleapis.com/maps/api/directions/"
+ output + "?" + params;
Log.d("taqg", url);
return url;
}
public void drawPath(String result) {
if (result != null) {
mMap.clear();
}
int height = 100;
int width = 100;
BitmapDrawable bitmapdraw = (BitmapDrawable) getResources().getDrawable(R.drawable.source);
Bitmap b = bitmapdraw.getBitmap();
Bitmap ssource = Bitmap.createScaledBitmap(b, width, height, false);
BitmapDrawable bitmapdraw1 = (BitmapDrawable) getResources().getDrawable(R.drawable.way);
Bitmap b1 = bitmapdraw1.getBitmap();
Bitmap sway = Bitmap.createScaledBitmap(
b1, width, height, false);
BitmapDrawable bitmapdraw2 = (BitmapDrawable) getResources().getDrawable(R.drawable.dest);
Bitmap b2 = bitmapdraw2.getBitmap();
Bitmap sdest = Bitmap.createScaledBitmap(b2, width, height, false);
LatLng Source = new LatLng(dsla, dslo);
mMap.addMarker(new MarkerOptions()
.position(Source)
.title("Source")
.icon(BitmapDescriptorFactory.fromBitmap(ssource)));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Source, 18));
LatLng path1 = new LatLng(dp1la, dp1lo);
mMap.addMarker(new MarkerOptions()
.position(path1)
.title("path")
.icon(BitmapDescriptorFactory.fromBitmap(sway)));
LatLng path2 = new LatLng(dp2la, dp2lo);
mMap.addMarker(new MarkerOptions()
.position(path2)
.title("path")
.icon(BitmapDescriptorFactory.fromBitmap(sway)));
LatLng dest = new LatLng(ddla, ddlo);
mMap.addMarker(new MarkerOptions()
.position(dest)
.title("Destination")
.icon(BitmapDescriptorFactory.fromBitmap(sdest)));
try {
// Tranform the string into a json object
final JSONObject json = new JSONObject(result);
Log.d("array", result);
JSONArray routeArray = json.getJSONArray("routes");
int i = routeArray.length();
String x = String.valueOf(i);
Log.d("length", x);
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<LatLng> list = decodePoly(encodedString);
Polyline line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.width(12)
.color(Color.parseColor("#FF0000"))//Google maps blue color
.geodesic(true)
);
/* for (int z = 0; z < list.size() - 1; z++) {
LatLng src = list.get(z);
LatLng desti = list.get(z + 1);
Polyline line = mMap.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(path1.latitude,path1.longitude),
new LatLng(path2.latitude,path2.longitude),
new LatLng(desti.latitude, desti.longitude))
.width(5).color(Color.BLUE).geodesic(true));
}
*/
} catch (Exception 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() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(GetCo.this);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected String doInBackground(Void... params) {
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
Log.d("jsonnnnnnnnnnnnnnn", json);
return json;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.hide();
if (result != null) {
Log.d("jsonppp", result);
drawPath(result);
}
}
}
}
Using Map Api V2 I have drawn a route on the map. Now i wish to save this route in my database.
So I need to get the lat/lng of points on the route say after each 100 meters which i will save as a polygon. How can i do it in Google Map V2 in android.
i am stuck on it from last 10 days but not getting a solution.
any help will be appriciable :)
public class NavigationActivity extends FragmentActivity {
public static final String TAG_SLAT = "sourcelat";
public static final String TAG_SLONG = "sourcelong";
public static final String TAG_DLAT = "destinationlat";
public static final String TAG_DLONG = "destinationg";
private static LatLng Source = null;
private static LatLng Destination = null;
private GoogleMap map;
private SupportMapFragment fragment;
private LatLngBounds latlngBounds;
private Button bNavigation;
private Polyline newPolyline;
private Marker smarker;
private Marker dmarker;
Geocoder geocoder;
private boolean isTraveling = false;
private int width, height;
private String sourcelat;
private String sourcelong;
private String destinationg;
private String destinationlat;
double slat;
double slong;
double dlat;
double dlong;
double d;
double tempDistance;
String distance;
ConnectionDetector cd;
Boolean isConnectingToInternet = false;
String ts;
LatLng latLng;
GPSTracker gps;
List<Address> addresses;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_navigation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
Intent in = getIntent();
sourcelat = in.getStringExtra(TAG_SLAT);
destinationlat = in.getStringExtra(TAG_DLAT);
destinationg = in.getStringExtra(TAG_DLONG);
sourcelong = in.getStringExtra(TAG_SLONG);
slat = Double.parseDouble(sourcelat);
slong = Double.parseDouble(sourcelong);
dlat = Double.parseDouble(destinationlat);
dlong = Double.parseDouble(destinationg);
Source = new LatLng(slat, slong);
Destination = new LatLng(dlat, dlong);
getSreenDimanstions();
fragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
map = fragment.getMap();
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
map.setTrafficEnabled(true);
ImageButton cureent_location = (ImageButton) findViewById(R.id.clocation);
cureent_location.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onLocationChanged();
}
});
if (!isTraveling) {
isTraveling = true;
findDirections(Source.latitude, Source.longitude, Destination.latitude, Destination.longitude, GMapV2Direction.MODE_DRIVING);
} else {
isTraveling = false;
}
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
public double calculateDistance(double fromLatitude,double fromLongitude,double toLatitude,double toLongitude)
{
float results[] = new float[1];
try {
Location.distanceBetween(fromLatitude, fromLongitude, toLatitude, toLongitude, results);
} catch (Exception e) {
if (e != null)
e.printStackTrace();
}
if (Source.equals(Destination)){
distance="0";
}
else {
int dist = (int) results[0];
if (dist <= 0)
return 0D;
DecimalFormat decimalFormat = new DecimalFormat("#.##");
results[0] /= 1000D;
distance = decimalFormat.format(results[0]);
double d = Double.parseDouble(distance);
double speed = 40;
double time = d / speed;
ts = manual(time);
Log.v("fdf", String.valueOf(ts));
}
return d;
}
private static String manual(double eta) {
int hour = (int) eta;
eta = (eta - hour) * 60;
int minutes = (int) eta;
eta = (eta - minutes) * 60;
int seconds = (int) eta;
eta = (eta - seconds) * 1000;
int ms = (int) eta;
//Log.d("ffgfh", String.valueOf(eta));
return String.format("%dHr %dMin ", hour, minutes);
}
#Override
protected void onResume() {
super.onResume();
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints) {
PolylineOptions rectLine = new PolylineOptions().width(5).color(Color.RED);
//MarkerOptions marker = new MarkerOptions().position(Source).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
MarkerOptions marker1 = new MarkerOptions().position(Destination).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
for(int i = 0 ; i < directionPoints.size() ; i++)
{
rectLine.add(directionPoints.get(i));
}
if (newPolyline != null)
{
newPolyline.remove();
}
newPolyline = map.addPolyline(rectLine);
//smarker = map.addMarker(marker);
dmarker = map.addMarker(marker1);
if (isTraveling) {
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
Dialog dialog_help = new Dialog(this);
dialog_help .requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog_help.setContentView(R.layout.title_multi_selectitems_dialog);
calculateDistance(slat, slong, dlat, dlong);
TextView dis = (TextView) dialog_help.findViewById(R.id.distance);
dis.setText("Distance " + distance + "Km ");
TextView tim = (TextView) dialog_help.findViewById(R.id.time);
tim.setText("Time " + ts);
dialog_help.setCancelable(true);
dialog_help.setTitle("Distance & Time" );
dialog_help.setCanceledOnTouchOutside(true);
dialog_help.show();
dialog_help.getWindow().setGravity(Gravity.CENTER);
dialog_help.getWindow().setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
dialog_help.getWindow().setLayout(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT);
}
else {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
}
private void getSreenDimanstions()
{
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
private LatLngBounds createLatLngBoundsObject(LatLng firstLocation, LatLng secondLocation)
{
if (firstLocation != null && secondLocation != null)
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstLocation).include(secondLocation);
return builder.build();
}
return null;
}
public void findDirections(double fromPositionDoubleLat, double fromPositionDoubleLong, double toPositionDoubleLat, double toPositionDoubleLong, String mode)
{
Map<String, String> map = new HashMap<String, String>();
map.put(GetDirectionsAsyncTask.USER_CURRENT_LAT, String.valueOf(fromPositionDoubleLat));
map.put(GetDirectionsAsyncTask.USER_CURRENT_LONG, String.valueOf(fromPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DESTINATION_LAT, String.valueOf(toPositionDoubleLat));
map.put(GetDirectionsAsyncTask.DESTINATION_LONG, String.valueOf(toPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DIRECTIONS_MODE, mode);
GetDirectionsAsyncTask asyncTask = new GetDirectionsAsyncTask(this);
try {
asyncTask.execute(map);
}catch (Exception e){
Toast.makeText(getBaseContext(), "Something went Wrong", Toast.LENGTH_SHORT).show();
}
}
public void onLocationChanged( ){
TextView cl = (TextView) findViewById(R.id.latlongLocation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
gps = new GPSTracker(NavigationActivity.this);
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
latLng = new LatLng(latitude, longitude);
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
String prmises = addresses.get(0).getAddressLine(1);
String city = addresses.get(0).getAddressLine(2);
String country = addresses.get(0).getAddressLine(3);
cl.setText(address + " " + prmises + " " + city + " " + country);
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
}
You can try it with this map application: http://maps.cloudmade.com/.
At first you create your route with waypoints. Click on the button "Get directions" (upper left corner) and create your route (clicking on the map). After that you can export (there is a button on the upper right corner) your route (include waypoints) to a gpx-or a json-file. You can load both files to a GIS.
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'm currently working on a google maps application i could display the route between two given (by the user) points, and now i'm trying to display some information ,for the user , as : duration between the two points and distance as well as showing alternative roads .
After searching i found out that i can add things to my URL such as mode, alternatives=true...
public class MapsActivity extends FragmentActivity {
private GoogleMap gm;
String Depart;
String Arrive;
TextView tvdirections;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapifNeeded();
ImageButton serch_button = (ImageButton) findViewById(R.id.btnSearch);
tvdirections=(TextView)findViewById(R.id.tvdirections);
serch_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog_button = new Dialog(MapsActivity.this);
dialog_button.setTitle("Voir itineraires");
dialog_button.setContentView(R.layout.dialog);
dialog_button.show();
final EditText edittxt1 = (EditText) dialog_button.findViewById(R.id.depart);
final EditText edittxt2 = (EditText) dialog_button.findViewById(R.id.arrive);
Button GoButton = (Button) dialog_button.findViewById(R.id.btnDialog);
GoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Depart = edittxt1.getText().toString();
Arrive = edittxt2.getText().toString();
if ((Depart.equals("") || Arrive.equals("")) || (Depart.equals(null) || Arrive.equals(null))) {
Toast.makeText(getApplicationContext(), "Veuillez entrer les points de depart et d'arrive", Toast.LENGTH_SHORT).show();
} else {
new ItineraryActivity(getApplicationContext(), gm, Depart, Arrive,tvdirections).execute();
dialog_button.cancel();
gm.clear();
}
}
});
}
});
}
#Override
protected void onResume() {
super.onResume();
setUpMapifNeeded();
}
public void OnChangeToHybrid(View view) {
gm.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
public void OnChangeToNormal(View view) {
gm.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
private void setUpMapifNeeded() {
if (gm == null) {
gm = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mymap)).getMap();
}
if (gm != null) {
setUpMap();
}
}
private void setUpMap() {
//gm.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("hi bouchra :)"));
//gm.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(0, 0), 18));
gm.setMyLocationEnabled(true);
gm.getUiSettings().setZoomControlsEnabled(true);
gm.getUiSettings().setCompassEnabled(true);
}
}
here is the other class
public class ItineraryActivity extends AsyncTask<Void,Integer,Boolean> {
private static final String TOAST_ERR_MAJ = "Impossible de trouver un itineraire";
private Context context;
private GoogleMap gm;
private String Depart;
private String Arrive;
private TextView tvdirections;
private final ArrayList<LatLng> lstLatLng = new ArrayList<LatLng>();
private NodeList nl1;
private NodeList nl2;
private Node node1=null;
private Node node2=null;
public ItineraryActivity(final Context context, final GoogleMap gMap, final String Depart, final String Arrive, final TextView tvdirections) {
this.context = context;
this.gm = gMap;
this.Depart = Depart;
this.Arrive = Arrive;
this.tvdirections = tvdirections;
//nl1 = null;
}
#Override
protected void onPreExecute() {
}
#Override
public Boolean doInBackground(Void... params) {
try {
//Construction de l'url a appeler
final StringBuilder url = new StringBuilder("http://maps.googleapis.com/maps/api/directions/xml?sensor=false");
url.append("&origin=");
url.append(Depart.replace(' ', '+'));
url.append("&destination=");
url.append(Arrive.replace(' ', '+'));
url.append("&alternatives=true&units=metric");
final InputStream stream = new URL(url.toString()).openStream();
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringComments(true);
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
final Document document = documentBuilder.parse(stream);
document.getDocumentElement().normalize();
final String status = document.getElementsByTagName("status").item(0).getTextContent();
if (!"OK".equals(status)) {
return false;
}
//On recupere les steps
final Element elementLeg = (Element) document.getElementsByTagName("leg").item(0);
final NodeList nodeListStep = elementLeg.getElementsByTagName("step");
final int length = nodeListStep.getLength();
//final NodeList distancelist= elementLeg.getElementsByTagName("distance");
for (int i = 0; i < length; i++) {
final Node nodeStep = nodeListStep.item(i);
if (nodeStep.getNodeType() == Node.ELEMENT_NODE) {
final Element elementStep = (Element) nodeStep;
//On decode les points du XML
decodePolylines(elementStep.getElementsByTagName("points").item(0).getTextContent());
}
}
nl1= document.getElementsByTagName("distance");
node1=nl1.item(0);
nl2=node1.getChildNodes();
node2=nl2.item(getNodeIndex(nl2, "text"));
return true;
} catch (final Exception e) {
return false;
}
}
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 void decodePolylines(final String encodedPoints) {
int index = 0;
int lat = 0, lng = 0;
while (index < encodedPoints.length()) {
int b, shift = 0, result = 0;
do {
b = encodedPoints.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 = encodedPoints.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
lstLatLng.add(new LatLng((double) lat / 1E5, (double) lng / 1E5));
}
}
//List<HashMap<String, String>> path = result.get(i);
protected void onPostExecute( final Boolean result) {
/*String distance = "";
String duration = "";*/
if (!result) {
Toast.makeText(context, TOAST_ERR_MAJ, Toast.LENGTH_SHORT).show();
} else {
final PolylineOptions polylines = new PolylineOptions();
polylines.color(Color.BLUE);
polylines.width(3);
//On construit le polyline
for (final LatLng latLng : lstLatLng) {
polylines.add(latLng);
}
final MarkerOptions markerA = new MarkerOptions();
markerA.position(lstLatLng.get(0));
markerA.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
final MarkerOptions markerB = new MarkerOptions();
markerB.position(lstLatLng.get(lstLatLng.size() - 1));
markerB.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
gm.moveCamera(CameraUpdateFactory.newLatLngZoom(lstLatLng.get(0), 10));
gm.addMarker(markerA);
gm.addPolyline(polylines);
gm.addMarker(markerB);
tvdirections.setText(""+node2);
}
}
Using JSON:
This example is thought to get data for only one route, but in order to work with more options the only thing you should know is that you'll have a "legs" JSONArray for each route.
final String str = "http://maps.googleapis.com/maps/api/directions/json?"
+ "origin=" + Start.latitude + "," + Start.longitude
+ "&destination=" + End.latitude + "," + End.longitude
+"&language=" +getResources().getConfiguration().locale.getDefault().getLanguage()
+ "&sensor=false&units=metric&mode=" + "walking"
+ "&alternatives=true";
URL url = new URL(str);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
StringBuilder jsonResults = new StringBuilder();
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray parentArray = jsonObj.getJSONArray("routes");
final JSONArray legArray = parentArray.getJSONObject(0).getJSONArray("legs");
//Distance
JSONObject distanceObj = legArray.getJSONObject(0).getJSONObject("distance");
distance = distanceObj.getInt("value"); //Value of distance
distance = distanceObj.getString("text"); //String that contains the distance value formated
//With duration is the same changing getJSONObject("distance") with getJSONObject("duration")