Currently developing an Android
application that returns the closest 20 location to the users current location.
Google Places API
is returning ~20 places close to the users location but not the closest 20 sorted by distance.
Looking at the Google Places API Documentation does not show anything that I can see to be incorrect.
GetPlaces.java
String types = "accounting|airport|amusement_park|aquarium|art_gallery|atm|bakery|bank|bar|beauty_salon|bicycle_store|book_store|bowling_alley|bus_station|cafe|campground|car_dealer|car_rental|car_repair|car_wash|casino|cemetery|church|city_hall|clothing_store|convenience_store|courthouse|dentist|department_store|doctor|electrician|electronics_store|embassy|establishment|finance|fire_station|florist|food|funeral_home|furniture_store|gas_station|general_contractor|grocery_or_supermarket|gym|hair_care|hardware_store|health|hindu_temple|home_goods_store|hospital|insurance_agency|jewelry_store|laundry|lawyer|library|liquor_store|local_government_office|locksmith|lodging|meal_delivery|meal_takeaway|mosque|movie_rental|movie_theater|moving_company|museum|night_club|painter|park|parking|pet_store|pharmacy|physiotherapist|place_of_worship|plumber|police|post_office|real_estate_agency|restaurant|roofing_contractor|rv_park|school|shoe_store|shopping_mall|spa|stadium|storage|store|subway_station|synagogue|taxi_stand|train_station|travel_agency|university|veterinary_care|zoo";
resourceURI = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="+myLocation.latitude+","+myLocation.longitude+"&radius=500&rankBy=distance&types="+ URLEncoder.encode(types, "UTF-8")+"&sensor=true&key=GOOGLE_MAPS_KEY";
try {
String url =resourceURI; //getURL(myLocation.latitude,myLocation.longitude);
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
HttpConnectionParams.setSoTimeout(httpParams, 30000);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
String response = (String) httpClient.execute(httpGet, responseHandler);
if (response != null) {
mResult = new JSONObject(response);
results = mResult.getJSONArray("results");
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
return null;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
catch (JSONException e) {
e.printStackTrace();
return null;
}
return results;
}
This returns valid JSON, but not the closest places to the passed in distance. I know for a fact that there are closer places than what the request is returning.
For example, I make a request at a known google place, but it is not showing the place I am currently at- but others that are farther.
Maybe you've already solved your problem, but I hope this can help (Focus on what is in bold):
radius - Defines the distance (in meters) Within Which to return Place results. The maximum allowed is 50 000 meters radius. Note That radius must not be included if rankby = distance (Described below under Optional parameters) is specified.
rankby — Specifies the order in which results are listed. Possible values are:
prominence (default). This option sorts results based on their importance. Ranking will favor prominent places within the specified area. Prominence can be affected by a Place's ranking in Google's index, the number of check-ins from your application, global popularity, and other factors.
distance. This option sorts results in ascending order by their distance from the specified location. When distance is specified, one or more of keyword, name, or types is required.
according: https://developers.google.com/places/documentation/search?hl=en
I have understood according to google documentation that you can not simultaneously send arguments "rankby" and "radius", you must use only one of them at the same time, this way you will get the results sorted by distance.
test the request doing this:
resourceURI = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?
location="+myLocation.latitude+","+myLocation.longitude+"&rankBy=distance
&types="+ URLEncoder.encode (types, "UTF-8") + "&sensor = true&
key = GOOGLE_MAPS_KEY";
to see how you do, good luck!
Hope this code will work..
private ArrayList<CLPlaceDTO> sortLocation(LatLng currentLatLng, ArrayList<?> alLocationDTO)
{
ArrayList<CLPlaceDTO> clPlaceDTOArrayList;
ArrayList<CLPlaceDTO> clPlaceDTOArrayList1 = new ArrayList<>();
double dCurrentLat = currentLatLng.latitude;
double dCurrentLong = currentLatLng.longitude;
Iterator<?> clIterator = alLocationDTO.iterator();
while (clIterator.hasNext())
{
clIterator.next();
clPlaceDTOArrayList = new ArrayList<>();
for (int j = 0; j < alLocationDTO.size(); j++)
{
CLLocationDTO clLocationDTO = (CLLocationDTO) alLocationDTO.get(j);
double dLat = clLocationDTO.getLatitude().doubleValue();
double dLng = clLocationDTO.getLongitude().doubleValue();
LatLng clNewLatLng = new LatLng(dLat, dLng);
double dDistance = getDistance(dCurrentLat, dCurrentLong, dLat, dLng);
CLPlaceDTO clPlaceDTO = new CLPlaceDTO(clLocationDTO.getAccountName(), clNewLatLng, dDistance);
clPlaceDTOArrayList.add(clPlaceDTO);
}
Collections.sort(clPlaceDTOArrayList, new CLSortPlaces(currentLatLng));
dCurrentLat = clPlaceDTOArrayList.get(0).getLatlng().latitude;
dCurrentLong = clPlaceDTOArrayList.get(0).getLatlng().longitude;
clPlaceDTOArrayList1.add(clPlaceDTOArrayList.get(0));
clIterator.remove();
}
return clPlaceDTOArrayList1;
}
public static double getDistance(double dbFromLatitude,double dbFromLongitude,double dbToLatitude,double dbToLongitude)
{
double dbRadiusMeters = EARTH_RADIUS * 1000 ; // Earth’s mean radius in meter
double dbLatitudeDiff = Math.toRadians(dbToLatitude - dbFromLatitude);
double dbLongitudeDiff = Math.toRadians(dbToLongitude - dbFromLongitude);
double a = Math.sin(dbLatitudeDiff / 2) * Math.sin(dbLatitudeDiff / 2) +
Math.cos(Math.toRadians(dbFromLatitude)) * Math.cos(Math.toRadians(dbToLatitude)) *
Math.sin(dbLongitudeDiff / 2) * Math.sin(dbLongitudeDiff / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = dbRadiusMeters * c;
return d; // returns the distance in meter
}
public class CLSortPlaces implements Comparator<CLPlaceDTO>
{
private LatLng currentLoc;
CLSortPlaces(LatLng current)
{
currentLoc = current;
}
@Override
public int compare(final CLPlaceDTO place1, final CLPlaceDTO place2)
{
return (int) (place1.dDistance - place2.dDistance);
}
}
public class CLPlaceDTO
{
public LatLng latlng;
public String sNameOfLocation;
public double dDistance;
public CLPlaceDTO(String sNameOfLocation, LatLng latlng,double dDistance)
{
this.sNameOfLocation = sNameOfLocation;
this.latlng = latlng;
this.dDistance=dDistance;
}
public CLPlaceDTO(String sNameOfLocation, LatLng latlng)
{
this.sNameOfLocation = sNameOfLocation;
this.latlng = latlng;
this.dDistance=dDistance;
}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With