Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Places Api sort by distance

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.

like image 508
Andrew Gable Avatar asked Mar 29 '14 03:03

Andrew Gable


2 Answers

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!

like image 182
Darq Roya Avatar answered Sep 18 '22 02:09

Darq Roya


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;
    }}
like image 39
Ramesh kumar Avatar answered Sep 19 '22 02:09

Ramesh kumar