I have written some code to search nearby places based on their prominence. Next, I'd like to have my app search places based on ascending distance from the user. In order to do that, I learned that I need to use rankby=distance but rankby does not allow a value for radius - so the following radius-based search doesn't work:
nearPlaces = googlePlaces.search(
gps.getLatitude(),
gps.getLongitude(),
radius,
types
);
I've seen several blogs and articles where people asked similar questions, but none of them provided an answer which seems to work. What should I be using, if not the above?
correct is rankBy=distance...
Keep the B capital in rankBy...
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?rankby=distance&";
public PlacesList search(double latitude, double longitude, double radius, String types)
throws Exception {
this._latitude = latitude;
this._longitude = longitude;
this._radius = radius;
//this._rankby=_rankby;
try {
HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
HttpRequest request = httpRequestFactory
.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
request.getUrl().put("key", API_KEY);
request.getUrl().put("location", _latitude + "," + _longitude);
// request.getUrl().put("radius", _radius);
request.getUrl().put("rankBy", _radius);
// in meters
request.getUrl().put("sensor", "false");
//request.getUrl().put("rankby", _rankby);
if(types != null)
request.getUrl().put("types", types);
PlacesList list = request.execute().parseAs(PlacesList.class);
// Check log cat for places response status
Log.d("Places Status", "" + list.status);
return list;
} catch (HttpResponseException e) {
Log.e("Error:", e.getMessage());
return null;
}
}
You can bypass it. I used 'GOOGLE PLACES WEB SERVICES'
https://developers.google.com/places/webservice/search :
get a JSON of all your places using PLACES API (use HttpURLConnection to send the request) :
String nearByPlaceSearchURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?"
+ "location=" + myLatPosition + "," + myLonPosition
+ "&radius=" + myPlaceDistanceMeters
+ "&types=" + myPlaceName
+ "&key=" + MyConstants.KEY_FOR_PLACES_AND_DISTANCES_API;
Parse the returned JSON and get the coordinates, LAT/LON, of each one of the places.
Get a JSON of all the distances from your current position to each one of the places using DISTANCE MATRIX API:
String distancesSearchURL = "https://maps.googleapis.com/maps/api/distancematrix/json?"
+ "origins=" + myLatPosition + "," + myLonPosition
+ "&destinations=" + allPlacesCoordinates
+ "&mode=walking"
+ "&key=" + MyConstants.KEY_FOR_PLACES_AND_DISTANCES_API;
Note that the distance is a walking,driving or cycling distance, which is the distance we are interested in. The radius distance (air distance) is not relevant. The walking/driving/cycling distances are bigger than the air distance.Therefore, for example, you can search for a place in radius of 10 km but the walking distance to it will be 11 km.
Create an Object for each one of the places with its name and distance from your current position as internal variables.
Generate an ArrayList containing all your Objects places.
Sort the ArrayList using the method comparator according to the distance.
Related
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");
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!
What I want to do is this:
I receive a list of directions/paths (that the user will have to follow using my app).
I am having trouble drawing the path on the map. The directions/paths contains the name of the streets, the coordinates of the streets and the segments of the streets.
I cant figure out how to draw the path/route on the map and make the route update - for example when the user moves (on the way) an icon to move indicating the progress of the user or the line drawn for the route gets shorter this really doesn't matter that much. So can you point me to tutorials which I can refer to?
I've seen a lot so far, but most of them get the directions from Google maps or the lines drawn are just straight lines from Start point to end point and doesn't fit the streets at all.
To achieve this, follow the below steps
Get list of ArrayList markerPoints;
Create your markers for it
single path,
LatLng origin = markerPoints.get(0);
LatLng dest = markerPoints.get(1);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
for multiple destination path, for example A-B-D-C etc
private List<String> getDirectionsUrl(ArrayList<LatLng> markerPoints) {
List<String> mUrls = new ArrayList<>();
if (markerPoints.size() > 1) {
String str_origin = markerPoints.get(0).latitude + "," + markerPoints.get(0).longitude;
String str_dest = markerPoints.get(1).latitude + "," + markerPoints.get(1).longitude;
String sensor = "sensor=false";
String parameters = "origin=" + str_origin + "&destination=" + str_dest + "&" + sensor;
String output = "json";
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
mUrls.add(url);
for (int i = 2; i < markerPoints.size(); i++)//loop starts from 2 because 0 and 1 are already printed
{
str_origin = str_dest;
str_dest = markerPoints.get(i).latitude + "," + markerPoints.get(i).longitude;
parameters = "origin=" + str_origin + "&destination=" + str_dest + "&" + sensor;
url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
mUrls.add(url);
}
}
return mUrls;
}
Call the above method from
List<String> urls = getDirectionsUrl(markerPoints);
if (urls.size() > 1) {
for (int i = 0; i < urls.size(); i++) {
String url = urls.get(i);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
}
}
the above code will call for to create multiple paths, like A-B, B-D, D-C etc
try following this tutorial. You should draw between user location and marker. On user side call function onLocationChange to get the actual position and redraw the line. http://wptrafficanalyzer.in/blog/driving-route-from-my-location-to-destination-in-google-maps-android-api-v2/
Follow this:Android Google Map V3 PolyLine cannot be drawn
It'll help.
You just need to parse the data received after hitting Google Directions API
I trying to match hardcoded latitude an longitude with dynamic latitude and longitude, but its not showing correct output, can anyone help me to sort out this error
My code is
String Log = "-122.084095";
String Lat = "37.422005";
try {
if ((Lat.equals(latitude)) && (Log.equals(longitude))) {
AudioManager audiM = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audiM.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getApplicationContext(),
"You are at home",
Toast.LENGTH_LONG).show();
} else {
AudioManager auMa = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
auMa.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(getApplicationContext(),
"You are at office ", Toast.LENGTH_LONG)
.show();
}
} catch (Exception e) {
e.printStackTrace();
}
it always goes for else part...
You don't want to use a String comparison here as you can't guarantee the level of accuracy with the real-time location.
The best way to handle this would be to determine the distance between the points and then determine if it's close enough for you to consider, approx, the same.
For this, we use distanceBetween or distanceTo
Docs are here and here
Examples can be found here. Here's one of those examples:
Location locationA = new Location("point A");
locationA.setLatitude(pointA.getLatitudeE6() / 1E6);
locationA.setLongitude(pointA.getLongitudeE6() / 1E6);
Location locationB = new Location("point B");
locationB.setLatitude(pointB.getLatitudeE6() / 1E6);
locationB.setLongitude(pointB.getLongitudeE6() / 1E6);
double distance = locationA.distanceTo(locationB);
The latitude and longitude are variables which vary from point to point, matter of fact they keep on changing while standing on the same spot, because it is not precise.
Instead of comparing the Strings, take a rounded value of the lat and long (in long or float ) and check those values within a certain range. That will help you out with the "Home" and "Office " thing.
For e.g :
String Log = "22.084095";
String Lat = "37.422005";
double lng=Double.parseDouble(Log);
double lat=Double.parseDouble(Lat);
double upprLogHome=22.1;
double lwrLogHome=21.9;
double upprLatHome=37.5;
double lwrLatHome=37.3;
// double upprLogOfc=;
// double lwrLogOfc=;
// double upprLatOfc=;
// double lwrLatOfc=;
if(lng<upprLogHome && lng>lwrLogHome && lat<upprLatHome &&lat>lwrLatHome )
{
System.out.println("You are Home");
}
/* else if(lng<upprLogOfc && lng>lwrLogOfc && lat<upprLatOfc &&lat>lwrLatOfc )
{
System.out.println("You are Home");
}*/
else
System.out.println("You are neither Home nor Ofc");
But for the negative lat long you have to reverse the process of checking.
your matching is okay but you probably should not check for a gps location like this.
You should convert the location to something where you can check that you are in 10m radius of the location.
A nicer way would be to leave the long/lat as doubles and compare the numbers.
if(lat > HOME_LAT - 0.1 && lat < HOME_LAT + 0.1 && ...same for lon... ){}
Try this,
Use google map api to pass lat and long value you will get formatted address. And also pass dynamic lat and lng value same google api you will get formatted address. And then match two formatted address you will get result. i suggest this way you can try this
Use this google api. http://maps.googleapis.com/maps/api/geocode/json?latlng=11.029494,76.954422&sensor=true
Reena, its very easy, Check out below code. You need to use "equalsIgnoreCase()" instead of
"equals".
if ((Lat.equalsIgnoreCase(latitude)) && (Log.equalsIgnoreCase(longitude))) {
should work
Example below :
// Demonstrate equals() and equalsIgnoreCase().
class equalsDemo {
public static void main(String args[]) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good-bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " +
s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " +
s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " +
s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " +
s1.equalsIgnoreCase(s4));
}
}
You can print dynamice Latitute and Longitute to Logcat and check with hardcoded Latitute and Longitute
am trying to integrate Google Places API into my app.
Now I am finding out my current location of the Phone, how do I embed the longitude and latitude which I have got into the following URL instead of "location=34.0522222,-118.2427778"
"https://maps.googleapis.com/maps/api/place/search/xml?location=34.0522222,-118.2427778&radius=500&types=restaurants&sensor=false&key=Your_API_Key"
Do you mean how do you do string manipulation such as (untested):
int latitude = ...;
int longitude = ...;
String preamble = "https://maps.googleapis.com/maps/api/place/search/xml?location=";
String postamble = "&radius=500&types=restaurants&sensor=true&key=";
String key = "Your_api_key";
String latStr = latitude + "";
String longStr = longitude + "";
String url = preamble + latStr + "," + longStr + postamble + key;
$lat = location[0];
$long = location[1];
Should work, but I use json for geting long and lat from google. Is better. I can check it again if not working.
Here is better json solution:
http://maps.googleapis.com/maps/api/geocode/json?address=Atlantis&sensor=true&oe=utf-8
You should change Atlantis to address