Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting search based on a particular country in the Google Maps Places API

I am using the Google Maps' Places API for autocompletion of location as user types. But how can I restrict the suggestions to a particular country?

Here is my javascript:

function initAutocomplete() {

    // Create the search box and link it to the UI element.
    var input = document.getElementById('autocomplete-input');
    var searchBox = new google.maps.places.SearchBox(input);

    // [START region_getplaces]
    // Listen for the event fired when the user selects a prediction and retrieve
    // more details for that place.
    searchBox.addListener('places_changed', function() {
        var places = searchBox.getPlaces();
        if (places.length == 0) {
            return;
        }
    });
}
like image 372
Abhilash Avatar asked Dec 29 '15 00:12

Abhilash


2 Answers

Fixed it by changing SearchBox to Autocomplete and passing an options with the requirements..Here is the code if someone needs.

function initAutocomplete() {

    // Create the search box and link it to the UI element.
    var input = document.getElementById('autocomplete-input');
    var options = {
        componentRestrictions: {country: 'fr'}
    };

    var searchBox = new google.maps.places.Autocomplete(input, options);

    // [START region_getplaces]
    // Listen for the event fired when the user selects a prediction and retrieve
    // more details for that place.
    searchBox.addListener('places_changed', function() {
        var places = searchBox.getPlaces();
        if (places.length == 0) {
            return;
        }
    });
}
like image 96
Abhilash Avatar answered Nov 04 '22 03:11

Abhilash


Note: I'm using Google Maps API v3 (v3.30.13)

@Abhilash's approach to the problem was nice to try with. But with his answer, I faced a problem: the autocomplete was working fine, but it didn't triggering the places_changed method. And there's no console error too.

Then with the answer by @geocodezip in another thread, I figured out that, the event fired up with Autocomplete is not places_changed, but place_changed (note the difference of singular form).

And there are other changes required if you want to proceed with place_changed, because with place_changed it return only a single place, not an array of places. So:

  • instead of .getPlaces() you have to use .getPlace()
  • instead of places.forEach(function(place) { ... } you have to work with place directly.

    var input = document.getElementById('pac-input');
    var restrictOptions = {
        componentRestrictions: {country: 'bd'}
    };
    var searchBox = new google.maps.places.Autocomplete(input, restrictOptions);
    
    searchBox.addListener('place_changed', function() {
    
        var place = searchBox.getPlace();
    
        if (place.length == 0) {
            return;
        }
    
        if (!place.geometry) {
            console.log("No details available for input: '" + place.name + "'");
            return;
        }
    
        // ...
    
    });
    

Caveat

The limitation is: with .SearchBox() google places search work even with random string, but with .Autocomplete() random string cannot find out any .geometry, hence cannot pinpoint to any matched area on the map. With .SearchBox() if you type "Name of a place", hit enter, it can point to Placename, Locality. But with .Autocomplete() without choosing from the autosuggestion[s] it cannot trigger the place's .geometry. The following console.log(place) displays the difference between random string and autocomplete chosen item:

Random place vs. autocomplete place

Aftermath

I's not satisfied with the outcome how .Autocomplete() worked for me. So until having a nicer solution, I decided to stick to the .SearchBox() method - though it's not restricting the search suggestions. But binding with bounds_changed it binds the search result a little bit, though it's not strict and satisfactory, but at least something's better than nothing. ¯\_(ツ)_/¯

// Bias the SearchBox results towards current map's viewport.
front_end_map.addListener('bounds_changed', function() {
    searchBox.setBounds(front_end_map.getBounds());
});

I, desperately am, looking forward for a bulletproof solution...

like image 28
Mayeenul Islam Avatar answered Nov 04 '22 03:11

Mayeenul Islam