google places autocomplete restrict to particular area - google-maps

My requirement is to get google places autocomplete suggestion only for Bangalore places, but I am not getting places only for Bangalore or within mention latitude longitude.
I want to retireve only below image places in autocomplete textfield.
can someone plz suggest how to achieve the same and where I am going wrong.
Javascript:
<script type="text/javascript">
function initialize1() {
var southWest = new google.maps.LatLng( 12.97232, 77.59480 );
var northEast = new google.maps.LatLng( 12.89201, 77.58905 );
var bangaloreBounds = new google.maps.LatLngBounds( southWest, northEast );
var options = {
bounds: bangaloreBounds,
types: ['(cities)'],
componentRestrictions: {country: 'in'}
};
var input = document.getElementById('searchTextFieldTo');
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
google.maps.event.addDomListener(window, 'load', initialize1);
</script>
TextField:
<input type="text" id="searchTextFieldTo" class="ui-timepicker-hour" style="width:350px;text-align:left;font-style:italic;" placeholder="Enter To location" autocomplete="on" />

Google Provides two ways to achieve this. If you are not satisfied because in countries like India it do not work well, because states and provisions here do not have rectangular or structure boundaries.
1.LatLngBounds (LatLng southwest, LatLng northeast): Where you can give latitude and longitude to form an rectangle.
2. Location (Lat,Lng) & Radius: Where you can give latitude and longitude to form a circle.
But the problem with these approaches they do not provide expected results if you are from countries like India, where states and provisions are not in structured shapes (Rectangular) as in USA.
If you are facing same issue than there is an hack.
With jQuery/Jacascript, you can attach functions which will consistently maintain city name in text input which is bounded with Autocomplete object of Places API.
Here it is:
<script>
$(document).ready(function(){
$("#locality").val(your-city-name) //your-city-name will have city name and some space to seperate it from actual user-input for example: “Bengaluru | ”
});
$("#locality").keydown(function(event) { //locality is text-input box whixh i supplied while creating Autocomplete object
var localeKeyword = “your-city-name”
var localeKeywordLen = localeKeyword.length;
var keyword = $("#locality").val();
var keywordLen = keyword.length;
if(keywordLen == localeKeywordLen) {
var e = event || window.event;
var key = e.keyCode || e.which;
if(key == Number(46) || key == Number(8) || key == Number(37)){
e.preventDefault();
}//Here I am restricting user to delete city name (Restricting use of delete/backspace/left arrow) if length == city-name provided
if(keyword != localeKeyword) {
$("#locality").val(localeKeyword);
}//If input-text does not contain city-name put it there
}
if(!(keyword.includes(localeKeyword))) {
$("#locality").val(localeKeyword);
}//If keyworf not includes city name put it there
});
</script>
(Image:) Before This Hack
(Image:) After This hack

As mentioned in my answer here:
It is currently not possible to restrict results to a specific locality. You can use bounds as you have done so above to bias results towards, but not restricted to places contained within the specified bounds.
If you believe restriction by locality would be a useful feature please file a Places API - Feature Request.
EDIT:
As per 2018-07 it's possible to define the types of places to be retrieved, like cities (which are locality or administrative_area3 according to the API). Check out full answer here.

I think you can try this.
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var autocomplete = new google.maps.places.Autocomplete(this, {
bounds: bangaloreBounds,
strictBounds: true,
});
autocomplete.addListener('place_changed', function () {
});
Note form xomena:
strictBounds option was added in version 3.27 of Maps JavaScript API which is currently (January 2017) the experimental version.

function initialize() {
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var options = {
bounds: bangaloreBounds,
componentRestrictions: {country: 'in'},
strictBounds: true,
};
var input = document.getElementById('autocomplete');
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
google.maps.event.addDomListener(window, 'load', initialize);

As in the current documentation for Google javascript Places API here, you can define an array of types of places to be retrieved. In the example below, I set it to retrieve only cities (which are, according to the API, locality or administrative_area3). You can set it retrieve regions, addresses, establishments and geocodes as well.
function initMap() {
var input = document.getElementById('my-input');
var options = {
types: ['(cities)']
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
// the rest of the code ...
}

Related

Is there another way to setComponentRestrictions to state instead of country?

I want to know if I can set the google API to display Washington state only
I tried to use setComponentRestriction function but it only works for setting country only.
this is the code that I used:
inputName.setComponentRestrictions({'country': ['us']});
I guess you're using Google Places Autocomplete?
You can't restrict by state.
You can bias the autocomplete results to favor a location or area (bounds) and use the strictBounds option to restrict the results only to this given bounds.
var washingtonStateBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(45.575378, -123.967677),
new google.maps.LatLng(49.006015, -116.790674));
var input = document.getElementById('pac-input');
var options = {
bounds: washingtonStateBounds,
strictBounds: true,
componentRestrictions: {
'country': ['us']
}
}
var autocomplete = new google.maps.places.Autocomplete(input, options);
see a sample here:
https://jsfiddle.net/woosmap/895pq7nu/

Autocomplete on google map API should return only cities

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAiv004_zrkpEL-v1u-LU6QYIkgv7yjT_M&language={{ Lang::getLocale() }}&libraries=places&" />
<script type="text/javascript">
google.maps.event.addDomListener(window, 'load', function () {
var options = {
types: ['(cities)']
};
var places = new google.maps.places.Autocomplete(document.getElementById('location'));
var inputLat = $("input[name*='lat']");
var inputLng = $("input[name*='lng']");
var inputPlaceId = $("input[name*='place_id']");
google.maps.event.addListener(places, 'place_changed', function () {
var place = places.getPlace();
var address = place.formatted_address;
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
var placeId = place.place_id;
inputLat.val(latitude);
inputLng.val(longitude);
inputPlaceId.val(placeId);
});
});
$('#location').keypress(function(e) {
if (e.which == 13) {
google.maps.event.trigger(autocomplete, 'place_changed');
return false;
}
});
</script>
I need it to display only cities, but somehow I get countries too.. I don't want to display continents and countries. please help
If you check the autocomplete documentation, it is stated here that:
the (cities) type collection instructs the Places service to return
results that match either locality or administrative_area3
So like you have done, you need the cities as types parameter.
What you can do is to specify the country in the Google API call with a help of region parameter. Just check this tutorial on how to do that.
Here is the sample request:
= javascript_include_tag "http://maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=places&region=UK"
For more information, check this related SO question it may give you an idea on how to solve this issue.
Google maps Autocomplete: output only address without country and city
Is there a way to get only the city name from Google Places API instead of getting the whole location?

Mixed results on google places autocomplete

I have this code
var input, defaultBounds, autocomplete_normal;
input = (document.getElementById('search_location'));
defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-90, -180),
new google.maps.LatLng(90, 180)
);
var options = {
bounds: defaultBounds,
types: ['(cities)']
};
autocomplete_normal = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(autocomplete_normal, 'place_changed', function () {
var place = autocomplete_normal.getPlace();
console.log(place);
});
When i search for "Coimbra, Portugal" the places Api return "Coimbra" as "locality" - as it should.
But if i replace types: ['(cities)'] with types: ['geocode'] the "Coimbra" is return as "administrative_area_level_2" and no other info about locality.
The code with types: ['(cities)'] is used on submit page in order to get a city. The code with types: ['geocode'] is used on a search form that in this case will not return correct results since the "locality" variable is blank.
I tried to replace geocode with '(regions)' but with the same results. Can you tell me why this is happening ? And why this is happening only for certain places ?
Administrative_area 2 are also cities...from their doc :
administrative_area_level_2 indicates a second-order civil entity below the country level. Within the United States, these administrative levels are counties. Not all nations exhibit these administrative levels.'
Geocoding response do not contain 'cities' and thus they are reverted to administrative_area_2.

limiting google maps autocomplete to UK address only

I've been looking at the example on:
http://code.google.com/apis/maps/documentation/javascript/examples/places-autocomplete.html
and have decided to incorporate it into my site.
Is it possible to limit the addresses to UK addresses only?
Try this:
var input = document.getElementById('searchTextField');
var options = {
types: ['(cities)'],
componentRestrictions: {country: 'tr'}//Turkey only
};
var autocomplete = new google.maps.places.Autocomplete(input,options);
You can't strictly/hard limit the locations that it finds, although there is a feature request in the system to do so, but you can set a 'bias' on the results. It's passed in as an argument to the autocomplete method as a google maps bounds object. Autocomplete will then favor locations within those boundaries. Note, however, that since this isn't a hard boundary, if there are matches for the search outside the boundaries it will return those.
From my usage it seems a bit buggy and can use some improvement - especially considering that anything outside your boundary is not tagged by proximity at all, so something one block outside the boundary is just as likely to show as something 1000 miles outside, so make sure you play around with getting the boundaries working right.
You can intercept the JSONP results that are returned by the google.maps.places.Autocomplete functionality and use them as you see fit, such as to limit by country and display the results.
Basically you redefine the appendChild method on the head element, and then monitor the javascript elements that the Google autocomplete code inserts into the DOM for JSONP. As javascript elements are added, you override the JSONP callbacks that Google defines in order to get access to the raw autocomplete data.
It's a bit of a hack, here goes (I'm using jQuery but it's not necessary for this hack to work):
//The head element, where the Google Autocomplete code will insert a tag
//for a javascript file.
var head = $('head')[0];
//The name of the method the Autocomplete code uses to insert the tag.
var method = 'appendChild';
//The method we will be overriding.
var originalMethod = head[method];
head[method] = function () {
if (arguments[0] && arguments[0].src && arguments[0].src.match(/GetPredictions/)) { //Check that the element is a javascript tag being inserted by Google.
var callbackMatchObject = (/callback=([^&]+)&|$/).exec(arguments[0].src); //Regex to extract the name of the callback method that the JSONP will call.
var searchTermMatchObject = (/\?1s([^&]+)&/).exec(arguments[0].src); //Regex to extract the search term that was entered by the user.
var searchTerm = unescape(searchTermMatchObject[1]);
if (callbackMatchObject && searchTermMatchObject) {
var names = callbackMatchObject[1].split('.'); //The JSONP callback method is in the form "abc.def" and each time has a different random name.
var originalCallback = names[0] && names[1] && window[names[0]] && window[names[0]][names[1]]; //Store the original callback method.
if (originalCallback) {
var newCallback = function () { //Define your own JSONP callback
if (arguments[0] && arguments[0][3]) {
var data = arguments[0][4]; //Your autocomplete results
//SUCCESS! - Limit results here and do something with them, such as displaying them in an autocomplete dropdown.
}
}
//Add copy all the attributes of the old callback function to the new callback function. This prevents the autocomplete functionality from throwing an error.
for (name in originalCallback) {
newCallback[name] = originalCallback[name];
}
window[names[0]][names[1]] = newCallback; //Override the JSONP callback
}
}
//Insert the element into the dom, regardless of whether it was being inserted by Google.
return originalMethod.apply(this, arguments);
};
James Alday is correct:
http://code.google.com/apis/maps/documentation/javascript/places.html#places_autocomplete
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(49.00, -13.00),
new google.maps.LatLng(60.00, 3.00));
var acOptions = {
bounds: defaultBounds,
types: ['geocode']
};
it is somewhat annoying as searching for Durham gives Durham, North Carolina as the second result, regardless of how you try to persuade it to region bias - you can set it to viewport map bounds and it'll still try to suggest NC state... The jQuery solution can be found here, but doesn't seem to give as many results as the v3 API.
http://code.google.com/p/geo-autocomplete/
The best way you would go about doing this, is to query the places api yourself and appending the queried string with your country. Or, of course, use the geo-autocomplete jQuery plugin.
Just change the google domain for the maps to your country domain and it will automatically search within your country only:
So:
http://maps.google.com/maps/api/geocode/xml?address={0}&sensor=false&language=en
To:
http://maps.google.nl/maps/api/geocode/xml?address={0}&sensor=false&language=nl
Try something like this.
// Change Bangalore, India to your cities boundary.
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var autocomplete = new google.maps.places.Autocomplete(this, {
bounds: bangaloreBounds,
strictBounds: true,
});
autocomplete.addListener('place_changed', function () {
});
I find that if you set the map to roughly where you want then set bounds to it, the search finds places in that area first. You do not to physically show the map.
It works better than giving random overseas addresses first, setting to country does not work.
The code for autocomplete to get latln is:
<div id="map_canvas"></div>
<input type="text" name="location" id="location" placeholder="Type location...">
<input type="text" name="loc_latitude" id="latitude">
<input type="text" name="loc_longitude" id="longitude">
and the JS is:
$(document).ready(function () {
var mapOptions = {
center: new google.maps.LatLng(52.41041560, -1.5752999),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var autocomplete;
autocomplete = new google.maps.places.Autocomplete((document.getElementById(searchInput)), {
types: ['geocode'],
});
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var near_place = autocomplete.getPlace();
document.getElementById('latitude').value = near_place.geometry.location.lat();
document.getElementById('longitude').value = near_place.geometry.location.lng();
});
});
$(document).on('change', '#'+searchInput, function () {
document.getElementById('latitude').value = '';
document.getElementById('longitude').value = '';
});
Not exactly what you asked for but it works for me.

Google Maps geocode: undefined latitude

Hitting a page with the follow script displays:
lat: undefined
lon: 51.5001524
Why is it that while lat is undefined, lon is not?
A working example can be found here.
Pull up your web console and see for yourself!
$(document).ready(function(){
var geocoder;
function codeAddress()
{
geocoder = new google.maps.Geocoder();
var address = 'London, England';
geocoder.geocode({'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
lat = results[0].geometry.location.Ia;
lon = results[0].geometry.location.Ja;
console.log("lat: " + lat);
console.log("lon: " + lon);
}
});
}
codeAddress();
});
</script>
</head>
<body>
</body>
</html>
While we're at it - what is the historical significance of Ia and Ja? I presume it relates to the Cartesian unit vectors i and j (predominately used in Engineering) though I'm not sure.
I found other examples online who use .lat for .Ia and .lng for .Ja
These, however, are returning in the console:
function () {
return this[a];
}
Just need a kick in the right direction.
Thank you.
I would use lat() and lng():
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
This is a designed behaviour of the geocoder: google shifts the identifiers in
geometry.location.Ia;
geometry.location.Ja;
on a weekly basis, i.e. from above to
geometry.location.Ja;
geometry.location.Ka;
and so on, so it is not possible to refer by id to the geocoder result object.
Chances are Google are using a javascript minifier (e.g. http://jscompress.com/) which renames all variables - hence they're subject to change on every build.