I am using Google Directions API to get routes between two locations with Way Points.
Currently what I am doing is getting direction details between two locations using Direction API and showing the result in Google Maps integrated inside my application. It works well as expected. This is how I did it:
private DirectionsResult getDirectionsDetails(String origin,String destination,TravelMode mode) {
Log.i("testtt"," Origin "+origin+" Destination "+destination);
DateTime now = new DateTime();
try {
return DirectionsApi.newRequest(getGeoContext())
.mode(mode)
.origin(origin)
.waypoints(waypoints.toArray(new String[0]))
.destination(destination)
.departureTime(now)
.await();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (com.google.maps.errors.ApiException e) {
e.printStackTrace();
return null;
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
setupGoogleMapScreenSettings(googleMap);
DirectionsResult results = getDirectionsDetails(origin,destination,TravelMode.DRIVING);
if (results != null) {
addPolyline(results, googleMap);
positionCamera(results.routes[overview], googleMap);
addMarkersToMap(results, googleMap);
}
}
private void setupGoogleMapScreenSettings(GoogleMap mMap) {
mMap.setBuildingsEnabled(true);
mMap.setIndoorEnabled(true);
mMap.setTrafficEnabled(true);
UiSettings mUiSettings = mMap.getUiSettings();
mUiSettings.setZoomControlsEnabled(true);
mUiSettings.setCompassEnabled(true);
mUiSettings.setMyLocationButtonEnabled(true);
mUiSettings.setScrollGesturesEnabled(true);
mUiSettings.setZoomGesturesEnabled(true);
mUiSettings.setTiltGesturesEnabled(true);
mUiSettings.setRotateGesturesEnabled(true);
}
private void addMarkersToMap(DirectionsResult results, GoogleMap mMap) {
mMap.addMarker(new MarkerOptions().position(new LatLng(results.routes[overview].legs[overview].startLocation.lat,results.routes[overview].legs[overview].startLocation.lng)).title(results.routes[overview].legs[overview].startAddress));
mMap.addMarker(new MarkerOptions().position(new LatLng(results.routes[overview].legs[overview].endLocation.lat,results.routes[overview].legs[overview].endLocation.lng)).title(results.routes[overview].legs[overview].endAddress).snippet(getEndLocationTitle(results)));
}
private void positionCamera(DirectionsRoute route, GoogleMap mMap) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(route.legs[overview].startLocation.lat, route.legs[overview].startLocation.lng), 12));
}
private void addPolyline(DirectionsResult results, GoogleMap mMap) {
List<LatLng> decodedPath = PolyUtil.decode(results.routes[overview].overviewPolyline.getEncodedPath());
mMap.addPolyline(new PolylineOptions().addAll(decodedPath));
}
But what I want is I want to load this direction result in the external Google Maps app. What I am asking is is there any way to pass the DirectionsResult object to Google Maps application via Intent so that it will show the routes in the app.
Reason why I want this is to avoid integrating Google Maps API to the project as it is not completely free anymore.
Pricing details
As I can see in your code, that you are not performing any calculations on the DirectionsDetails given by DirectionsApi you can open the pass your location coordinates in google maps.
By default, Google maps always loads the best available route according to current traffic and time:
String geoUri = "http://maps.google.com/maps?q=loc:" + lat + "," + lng + " (" + mTitle + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUri));
context.startActivity(intent);
If you want to add waypoints in between your source and destination you can have a look at this answer.
If you want, you can find the route through DirectionsApi and process the data for your internal analytics for eg. approx time to travel between his location and new location, distance etc.
Related
I am using Mapbox (4.2.1) to draw a line from my position to a target position. I have the intention of using the straight line as an extremely basic navigation aid. As such I am re-drawing the guide line OnMyLocationChanged(). However it appears that as my location changes it will draw the line to my new location but MyLocationView (User icon) does not update in accordance (See image below).
They will eventually end up meeting again but it takes some time. It seems that the line is getting drawn inside the accuracy radius, however I would prefer if it could draw the line straight from the user icon.
Is there a simple way to draw a line between the user (The actual icon on the map) and a location which updates as the user moves?
My OnMyLocationChanged is:
MapboxMap.OnMyLocationChangeListener listner = new MapboxMap.OnMyLocationChangeListener(){
#Override
public void onMyLocationChange(final #Nullable Location locationChanged) {
//If we are not targeting anything or we are not tracking location
if(target == null || !map.isMyLocationEnabled()) return;
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(MapboxMap mapboxMap) {
//Log.i("LOC-MAPLINE", "Drawing from mapLoc call");
//Error if we don't have a location
if(!mapboxMap.isMyLocationEnabled() || locationChanged == null) return;
LatLng[] points = new LatLng[2];
final Location myLoc = locationChanged;
LatLng loc = new LatLng(myLoc.getLatitude(), myLoc.getLongitude());
LatLng dest = new LatLng(target.getLatitude(), target.getLongitude());
points[0] = loc;
points[1] = dest;
mapboxMap.removeAnnotations();
loadMarker(target);
PolylineOptions poly = new PolylineOptions()
.add(points)
.color(Color.parseColor("#3887be"))
.width(5);
line = mapboxMap.addPolyline(poly);
}
});
}
};
Any assistance is greatly appreciated, thank you!
EDIT (In regards to possible duplicate question - Google direction route from current location to known location)
I believe my question is different for a few reasons.
I am more concerned on getting the location of the user icon overlay rather than actual location (Accuracy issue)
I am not interested in getting turn for turn directions (Like those from a directions API)
I am using Mapbox rather than google maps (Not too sure but there could be some differences).
Nevertheless that question does not seem to answer my question
According to documentation you need only implement this method passing your currentLocation (origin) and destination
private void getRoute(Position origin, Position destination) throws ServicesException {
MapboxDirections client = new MapboxDirections.Builder()
.setOrigin(origin)
.setDestination(destination)
.setProfile(DirectionsCriteria.PROFILE_CYCLING)
.setAccessToken(MapboxAccountManager.getInstance().getAccessToken())
.build();
client.enqueueCall(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().getRoutes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
// Print some info about the route
currentRoute = response.body().getRoutes().get(0);
Log.d(TAG, "Distance: " + currentRoute.getDistance());
Toast.makeText(
DirectionsActivity.this,
"Route is " + currentRoute.getDistance() + " meters long.",
Toast.LENGTH_SHORT).show();
// Draw the route on the map
drawRoute(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
Toast.makeText(DirectionsActivity.this, "Error: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void drawRoute(DirectionsRoute route) {
// Convert LineString coordinates into LatLng[]
LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
List<Position> coordinates = lineString.getCoordinates();
LatLng[] points = new LatLng[coordinates.size()];
for (int i = 0; i < coordinates.size(); i++) {
points[i] = new LatLng(
coordinates.get(i).getLatitude(),
coordinates.get(i).getLongitude());
}
// Draw Points on MapView
map.addPolyline(new PolylineOptions()
.add(points)
.color(Color.parseColor("#009688"))
.width(5));
}
reference https://www.mapbox.com/android-sdk/examples/directions/
I am trying to set a marker in google maps by giving the latitude and longitude of a certain place after finding places by using this:
public void findPlace() {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_ADDRESS)
.build();
try {
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.setFilter(typeFilter)
.build(getActivity());
getActivity().startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
//to add marker for destination location
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
From this i get the place and i am using the following to get lat and long of the place searched:
Place place = PlaceAutocomplete.getPlace(MainActivity.this, data);
Log.e("lat and long", place.getLatLng().latitude + place.getLatLng().longitude )
after this i am trying to set marker to that lat and long using this method i created :
protected Marker createMarker(double latitude, double longitude) {
Logger.e("inside" ,"create marker");
return mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title("Destination")
.snippet("Snippet Destination").icon(BitmapDescriptorFactory.fromResource(R.drawable.black)));
}
and this method seems to work only inside onverride method onMapReady.
How can I use it after button click?
Call below method when you want put marker on map.
public Marker placeMarker(EventInfo eventInfo) {
Marker m = getMap().addMarker(new MarkerOptions().position(eventInfo.getLatLong()).title(eventInfo.getName()));
return m;
}
i have to show multiple location on the Native Google Map Application (MapView is not implemented in our application ).i have all the lat- long of all the geo Points . how can i pass the intent to show the multiple points on Native Google Map Application.
i know to show a point on Google map using the following Code.
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
please suggest how to do the needful changes.
Thanks :)
You can pass the names of the places that you want to show in the Map from the other Activity to the present Activity and then implement Markers to show them in the Map. For this you have to implement Google Map in the present Activity and I hope you have done that. :)
The below code shows multiple locations on a Google Map:
private void AddMarkers(GoogleMap googleMap)
{
try {
Intent intent = getIntent();
Bundle extras = intent.getExtras();
Geocoder geocoder = new Geocoder(context);
Origin_Map = extras.getString(MainActivity.ORIGIN_MAP);
Destination_Map = extras.getString(MainActivity.DESTINATION_MAP);
Addr_Origin = geocoder.getFromLocationName(Origin_Map, 1);
Addr_Dest = geocoder.getFromLocationName(Destination_Map, 1);
if (Addr_Origin.size() > 0) {
latitude_origin = Addr_Origin.get(0).getLatitude();
longitude_origin = Addr_Origin.get(0).getLongitude();
}
if (Addr_Dest.size() > 0) {
latitude_destination = Addr_Dest.get(0).getLatitude();
longitude_destination = Addr_Dest.get(0).getLongitude();
}
Marker m1 = googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude_origin, longitude_origin)).title(Origin_Map).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
Marker m2 = googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude_destination, longitude_destination)).title(Destination_Map).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
} catch (Exception e) {
e.printStackTrace();
}
}
And call this method once your map is ready!
#Override
public void onMapReady(GoogleMap googleMap)
{
AddMarkers(googleMap);
}
Hope this helps!!
Judging by this it is not possible. Also the question is a duplicate of this.
Now I'm using android map clicklistener to allow user to choose location from map. When the click the map the chosen location latitude and longitude are printed correctly in the toast, then I send this data to another fragment through bundle.
On android marshmallow devices it always transferred with null value, even it's working properly with all other versions.
I don't know what is the problem, so I'll be blessed for any help
Here is my code
try {
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
CameraUpdate Update = CameraUpdateFactory.newLatLngZoom(latLng, 10);
map.animateCamera(Update);
final Marker TP = map.addMarker(new MarkerOptions().position(latLng).title(""));
TP.setDraggable(true);
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
Toast.makeText(getActivity(), point.toString(), Toast.LENGTH_SHORT).show();
String latMap = String.valueOf(point.latitude);
String lngMap = String.valueOf(point.longitude);
((MainActivity)getActivity()).aqarLat = String.valueOf(point.latitude);;
((MainActivity)getActivity()).aqarLong = String.valueOf(point.longitude);
myBundle = new Bundle();
myBundle.putString("latMap" , latMap);
myBundle.putString("lngMap" , lngMap);
sharedPreferences.edit().putString("latMap", String.valueOf(point.latitude)).commit();
sharedPreferences.edit().putString("longMap", String.valueOf(point.longitude)).commit();
TP.setPosition(point);
}
});
} catch (Exception e) {
e.printStackTrace();
}
Thanks in advance
Is it possible to use it as library project for my application,i want to use Android Google Maps real app search-ability functionality. How can i do it,is it possible?
Thanks in advance..
EDIT:
I have shown Google Map in my app successfully, I want to include Google Map search functionality means that I can able to search any location in the world in auto suggested field and by selecting a particular location and move marker to that location. so how can I?
I tried this and this but not getting auto suggested text why I don't know..
I want like:
step1: show map with search box
step2: while entering text it should auto suggest.
step3: when click on particular name move map to that location
You can easily provide that kind of search functionality by using Places API and Geocode API (Both will help you according to your usecase).
Read the below Documentation for your assistance.
GeoCode API
Places API
I would recommend to use Places API for your need ( As per my observation on your usecase). But you could also use geocode, If you needed.
Many working reference and examples are there.
For startup, below are my reference :
PlacesAPI AutoComplete feature, Hotel Finder with Autocomplete
GeocodeAPI Simple GeoCoding
NOTE :
I have suggested javascript API. But not sure whether it will help you in Android environment (I dont know anything about android environment).
No single Api can help you have to use multiple google api's
Step1. Implement Google Place autocomplete Read this
Step2. You have to geocode means you have to convert address to latitude and longitude check this
Step3. Now You can plot these lat-long on the map.
This works for me.
I think you should take a look at the Google Maps API for Android at https://developers.google.com/maps/documentation/android/
The Google Search Appliance doesn't have any mapping or geo search features right now.
This is how I did it ---
Android Manifest file should contain the following lines:
<uses-library
android:name="com.google.android.maps"
android:required="true" >
</uses-library>
<!-- You must insert your own Google Maps for Android API v2 key in here. -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="<put your api key value here>" />
Location XML file should have the following apart from anything extra:
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Location java file should have something like this:
View mapView = null;
private GoogleMap mMap;
mMap = supportMapFragment.getMap();
mapView = (View) view.findViewById(R.id.map);
SupportMapFragment supportMapFragment = (SupportMapFragment) fragmentManager
.findFragmentById(R.id.map);
if(mMap != null){
mMap.setMyLocationEnabled(true);
}
if(mMap != null)
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng latLng) {
new EditMap().execute("", String.valueOf(latLng.latitude), String.valueOf(latLng.longitude));
}
});
class EditMap extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* getting Albums JSON
* */
protected String doInBackground(String... args) {
String address = args[0];
double latitude = Double.parseDouble(args[1]);
double longitude = Double.parseDouble(args[2]);
return editMap(address, latitude, longitude);
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String result) {
if(!result.equals(""))
ToastUtil.ToastShort(getActivity(), result);
else {
mMap.clear();
mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).title(attvalue));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 11));
}
}
}
NOTE:
These are the minimal requirements for the setting of location as you choose from Map that fills the location in your text.
There is a background thread that runs as you long press the location in a map.
The listener defined for that is setOnMapLongClickListener as you see above.
The execution will place the marker to the exact location you chose to mark as set.
There will be a done button after you have chosen the location by a marker. This done button will confirm what you have chosen and will set that on a textfield for you.
The above code uses the method editMap to edit the map location.
The implementation is as done here:
private String editMap(String address, double latitude, double longitude ) {
String keyword = null;
try {
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
if(!address.equals("")){
keyword = address;
java.util.List<android.location.Address> result = geocoder
.getFromLocationName(keyword, 1);
if (result.size() > 0) {
lat = (double) result.get(0).getLatitude();
lng = (double) result.get(0).getLongitude();
attvalue = address;
} else {
return "Record not found";
}
} else {
String sUrl = "http://google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=true";
DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(sUrl);
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if(status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
try{
JSONObject jsonObject = new JSONObject(data);
JSONArray results = jsonObject.getJSONArray("results");
JSONObject addressObject = results.getJSONObject(0);
JSONArray addressComp = addressObject.getJSONArray("address_components");
String city = "", state = "";
for(int i=0; i < addressComp.length(); i++){
JSONArray types = addressComp.getJSONObject(i).getJSONArray("types");
if(city.equals("") && types.getString(0).equals("locality"))
city = addressComp.getJSONObject(i).getString("long_name");
if(state.equals("") && types.getString(0).equals("administrative_area_level_1"))
state = addressComp.getJSONObject(i).getString("long_name");
if(!city.equals("") && !state.equals(""))
break;
}
attvalue = city + ", " + state;
} catch (JSONException e1) {
e1.printStackTrace();
}
lat = latitude;
lng = longitude;
}else{
return "Location Not Found";
}
}
} catch (IOException io) {
return "Connection Error";
}
return "";
}
I hope this is enough to help you out.