I want to develop an Android application with track my route on google map.is it possible?if yes please can you tell me what is the API and any sample code link?
Follow this link Google Maps Android: How can i draw a route line to see directions & save all the latitude longitude valu for tracking the location .
Use api for getting direction
"http://maps.googleapis.com/maps/api/directions/json?"
+ "origin=" + start.latitude + "," + start.longitude
+ "&destination=" + end.latitude + "," + end.longitude
+ "&sensor=false&units=metric&mode=driving";
or
If you only want to track the location use
public void onLocationChanged(Location location) {
if (lastLocationloc == null) {
lastLocationloc = location;
}
//public void setPoints (List<LatLng> points)
LatLng LatLng_origin = new LatLng( 13.133333, 78.133333); //kolar
LatLng LatLng3 = new LatLng(21.4949767, 86.942657999); // bbsr
TextView tvLocation = (TextView) findViewById(R.id.add);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(10));
tvLocation.setText("Latitude:" + latitude + ", Longitude:" + longitude);
}
Any more doubt ??
Related
I was using google directions api to get the route between two latlng points and plotting it on a google map. The issue is that i can optimize the route when adding waypoints but i can't control the optimization criteria. The code i am using for creating the request url is :
private String getDirectionsUrl(LatLng origin, LatLng dest) {
// Origin of route
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
// Destination of route
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Waypoints
String waypoints = "";
for (int i = 0; i < markerPoints.size(); i++) {
LatLng point = (LatLng) markerPoints.get(i);
if (i == 0)
waypoints = "waypoints=optimize:true|";
if (i == markerPoints.size() - 1) {
waypoints += point.latitude + "," + point.longitude;
} else {
waypoints += point.latitude + "," + point.longitude + "|";
}
}
// Building the parameters to the web service
String parameters = str_origin + "&" + str_dest + "&" + sensor + "&" + waypoints + "&mode=driving&key=YOUR_API_KEY";
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
return url;
}
In short, i want to add optimization criteria in this string. Is it possible or do i have to enable alternate routes and manually calculate the travel distance of each path and choose the shortest?
DIRECTION_URL_API = "https://maps.googleapis.com/maps/api/directions/json?"
DIRECTION_URL_API + "origin=" + origin + "&destination=" + destination + "&sensor=true" + "&mode=" +typeOpt+"&key=" + GOOGLE_API_KEY ;
I am using this format but its not working
Please suggest me :)
You can find distance following way
http://maps.googleapis.com/maps/api/directions/json?origin=21.1702,72.8311&destination=21.7051,72.9959&sensor=false&units=metric&mode=driving
origin=lat1,long1
destination=lat2,long2
Please use the below method to calculate the distance between two points
/**
* Returns Distance in kilometers (km)
*/
public static String distance(double startLat, double startLong, double endLat, double endLong) {
Location startPoint = new Location("locationA");
startPoint.setLatitude(startLat);
startPoint.setLongitude(startLong);
Location endPoint = new Location("locationA");
endPoint.setLatitude(endLat);
endPoint.setLongitude(endLong);
return String.format("%.2f", startPoint.distanceTo(endPoint) / 1000); //KMs
}
Method usage -
String mDistance = distance(startLat,
startLong,
endLat,endLng)).concat("km");
I am using drawable images for marker icons on a route. The base of the image does not appear at the point but rather more in the middle.
Can this be addressed?
Double latitude = new Double(getString(R.string.sagrada_latitude));
Double longitude = new Double(getString(R.string.sagrada_longitude));
final Position origin = Position.fromCoordinates(longitude, latitude);
latitude = new Double(getString(R.string.mataro_latitude));
longitude = new Double(getString(R.string.mataro_longitude));
final Position destination = Position.fromCoordinates(longitude, latitude);
// Create an Icon object for the marker to use
IconFactory iconFactory = IconFactory.getInstance(this);
Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.green_pin);
final Icon greenPinIcon = iconFactory.fromDrawable(iconDrawable);
iconDrawable = ContextCompat.getDrawable(this, R.drawable.red_pin);
final Icon redPinIcon = iconFactory.fromDrawable(iconDrawable);
// Setup the MapView
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(MapboxMap mapboxMap) {
map = mapboxMap;
// Add origin and destination to the map
LatLng originLatLng = (new LatLng(origin.getLatitude(), origin.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(originLatLng)
.title("Origin")
.snippet("current location: (" + origin.getLatitude() + ", " + origin.getLongitude() + ")")
.icon(greenPinIcon));
Log.d(TAG, "getMapAsync(): destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")");
LatLng destinationLatLng = (new LatLng(destination.getLatitude(), destination.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 5000);
// Get route from API
try {
getRoute(origin, destination);
}
catch (ServicesException servicesException) {
Log.e(TAG, servicesException.toString());
servicesException.printStackTrace();
}
}
});
}
private void getRoute(Position origin, Position destination) throws ServicesException {
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());
Double km = currentRoute.getDistance() / 1000;
// there are 4 digits to the right of the decimal, make it 2
String kilometers = km.toString();
int index = kilometers.lastIndexOf(".");
kilometers = kilometers.substring(0, index + 3);
Toast.makeText(
DirectionsActivity.this,
"Route is " + kilometers + " kilometers",
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();
}
});
}
A side question ... the Position.fromCoordinates method:
private Position(double longitude, double latitude, double altitude)
takes the arguments in order of longitude then latitude, not latitude then longitude as one might expect. Why?
Edit:
Changed MarkerOptions to MarkerViewOptions and the icons moved even further away. Also tried .anchor(0,0) which had no effect.
Also, with default Icons (which are off):
Icon:
// Mapbox dependencies
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:4.1.1#aar') {
transitive = true
}
compile ('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0#aar'){
transitive=true
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.3.1#aar') {
transitive = true
}
You either need to add padding to the bottom of the marker icon png or a better option would be using MarkerViewOptions() instead. They give more options then the GL markers your currently using including anchor. By default the anchoring is center bottom. So one of you markers would look like this:
mapboxMap.addMarker(new MarkerViewOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
To answer your other question, why position takes in longitude, latitude in that order, many of the Mapbox APIs consume coordinates in that order. The bigger question is why does the Position object exist when LatLng is found already in the Map SDK? This is because the objects would conflict since they are found in separate SDKs yet are typically used together. It is something we look forward to changing in the near future.
EDIT: first you need to remove the mapbox-android-directions, this is an old, non supported, SDK we have deprecated. Mapbox Android Services (MAS) is it's replacement and uses Mapbox Directions V5. Use this example which shows how to properly make a directions call using MAS and add the markers to the map. Using the coordinates found in your question, the result looks like this:
My goal is to do autocomplete prediction using Google Places API, and now I want to make some kind algorithm that will take current location lat and lng, and make a prediction of places only in 100-200 km diameter.
So, at this moment I get user's current location lat and lng, how to set 100-200 km?
private void getCurrentLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
mLatLonBounds = new LatLngBounds(new LatLng(latitude,longitude),
new LatLng(latitude,longitude));
Log.d("myTag","lat = "+mLatLonBounds.northeast.latitude+" ,lon = "+mLatLonBounds.northeast.longitude);
//Log.d("myTag","lat = "+mLatLonBounds.southwest.latitude+" ,lon = "+mLatLonBounds.southwest.longitude);
}else {
//some code
}
}
Here is how I set bounds to auto prediction:
#Nullable
private ArrayList<AutoCompletePlace> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(Constants.AUTO_COMPLETE_TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
**mBounds**, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(Constants.AUTO_COMPLETE_TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(Constants.AUTO_COMPLETE_TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Copy the results into our own data structure, because we can't hold onto the buffer.
// AutocompletePrediction objects encapsulate the API response (place ID and description).
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
// Get the details of this prediction and copy it into a new PlaceAutocomplete object.
resultList.add(new AutoCompletePlace(prediction.getPlaceId(),
prediction.getDescription()));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(Constants.AUTO_COMPLETE_TAG, "Google API client is not connected for autocomplete query.");
return null;
Example my current location 48.6180288,22.2984587.
UPDATE: Before the Francois Wouts give me the answer, I found another solution on stackoverflow, you can use it too.
public static final LatLngBounds setBounds(Location location, int mDistanceInMeters ){
double latRadian = Math.toRadians(location.getLatitude());
double degLatKm = 110.574235;
double degLongKm = 110.572833 * Math.cos(latRadian);
double deltaLat = mDistanceInMeters / 1000.0 / degLatKm;
double deltaLong = mDistanceInMeters / 1000.0 / degLongKm;
double minLat = location.getLatitude() - deltaLat;
double minLong = location.getLongitude() - deltaLong;
double maxLat = location.getLatitude() + deltaLat;
double maxLong = location.getLongitude() + deltaLong;
Log.d("Location", "Min: " + Double.toString(minLat) + "," + Double.toString(minLong));
Log.d("Location","Max: "+Double.toString(maxLat)+","+Double.toString(maxLong));
// Set up the adapter that will retrieve suggestions from the Places Geo Data API that cover
// the entire world.
return new LatLngBounds(new LatLng(minLat,minLong),new LatLng(maxLat,maxLong));
According to Wikipedia, you probably want to allow around 1 degree in each direction around the user's location to cover 100-200km. The exact area covered will depend on where the user is, but this should be a good enough approximation for most use cases.
Try the following, for example:
double radiusDegrees = 1.0;
LatLng center = /* the user's location */;
LatLng northEast = new LatLng(center.latitude + radiusDegrees, center.longitude + radiusDegrees);
LatLng southWest = new LatLng(center.latitude - radiusDegrees, center.longitude - radiusDegrees);
LatLngBounds bounds = LatLngBounds.builder()
.include(northEast)
.include(southWest)
.build();
I believe this should work correctly even across the antemeridian. Let me know how you go!
I've an app that gets the current user's location from a location service. When i get the lon and lat from the location object, they are as follows
lat = 53.653770446777344
lon = -1.520833969116211
.
I then store these in a GeoPoint object which is passed to a query string for Google Servers. This eventually plots a polyline between the current location and a destination.
It all works fine and the polyline is drawn, however it is drawn incorrectly as the current location is set about 100 mile away. I've logged out some values and there is a loss of precision when the lon and lat get passed to the geopoint.
How can i get around this.
#Override
public void onLocationChanged(Location location) {
lati = (location.getLatitude());
lngi = (location.getLongitude());
startAddr = new GeoPoint((int)lati, (int)lngi);
Log.e(TAG, "lat = " + lati);
Log.e(TAG, "lon = " + lngi);
Log.e(TAG, "lat after cast = " + (int)(lati * 1000000));
Log.e(TAG, "lon after cast = " + (int)(lngi * 1000000));
locationManager.removeUpdates(this);
StringBuilder sb = new StringBuilder();
sb.append("http://maps.google.com/maps/api/directions/json?origin=");
sb.append(startAddr);
sb.append("&destination=");
sb.append(endAddr);
sb.append("&sensor=false");
stringUrl = sb.toString();
Log.e(TAG, "url = " + stringUrl);
AsyncGetRoute agr = new AsyncGetRoute();
agr.execute();
.
11-15 12:45:17.280: E/GetClientDirections(23220): lat = 53.653770446777344
11-15 12:45:17.280: E/GetClientDirections(23220): lon = -1.520833969116211
11-15 12:45:17.280: E/GetClientDirections(23220): lat after cast = 53653770
11-15 12:45:17.280: E/GetClientDirections(23220): lon after cast = -1520833
11-15 12:45:17.290: E/GetClientDirections(23220): url = http://maps.google.com/maps/api/directions/json?origin=53,-1&destination=AL73EZ&sensor=false
This is the problem:
startAddr = new GeoPoint((int)lati, (int)lngi);
This truncates the fractions, so effectively for your input, your result is:
startAddr = new GeoPoint(53, -1);
As the API doc says, the GeoPoint accepts integer values: the two angles multiplied by 10^6. And because of this, the coordinates given would correspond to these values:
Latitude: 0.000053
Longitude: -0.000001
You should multiply first with 10^6, then truncate, so you should try:
startAddr = new GeoPoint((int)(lati*1000000.0), (int)(lngi*1000000.0));