Google maps autocomplete to restrict places shown in a specific country? - javascript

I am using google maps autocomplete correctly, however I want to restrict all the places shown to a specific country.
What modifications shall I do into the code in order to achieve that?
function initAutocomplete() {
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{types: ['geocode']});
}
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
autocomplete.setBounds(circle.getBounds());
})
;
}
}

Use the componentRestrictions option to restrict the autocomplete search to a particular country. The following code restricts the results to cities within France.
var input = document.getElementById('searchTextField');
var options = {
types: ['(cities)'],
componentRestrictions: {country: 'fr'}
};
autocomplete = new google.maps.places.Autocomplete(input, options);

just try adding it after '{types:[geocode]}'
autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),
{types: ['geocode'], componentRestrictions: {country: 'fr'}});

Related

GoogleMap Custom AutoComplete 1 Country

Good afternoon! I found a good code on the web, GoogleMap Custom AutoComplete, you can see it here:
https://embed.plnkr.co/IWj3w4/
In the js script, there are several lines like this:
function initialize() {
autocomplete = new google.maps.places.Autocomplete(
/** #type {HTMLInputElement} */
(document.getElementById('autocomplete')), {
types: ['geocode']
});
// When the user selects an address from the dropdown,
// populate the address fields in the form.
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
});
autocomplete_postalcode = new google.maps.places.Autocomplete(
(document.getElementById("AutocompletePostalCode")), {
types: ['(regions)'],
componentRestrictions: {country: 'fr'}
});
As you can see from the code, it should only work for the "FR" country, but it works worldwide. How to make 1 specific country in this code? For example USA or Canada?
Thanks a lot! I hope for your help

Reinitializing initAutocomplete Google Maps API Places autocomplete upon dynamically-loaded HTML input text element target

On initial page load this script:
<script src="https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places&callback=initAutocomplete" async defer></script>
along with the functions I've shared below are loading to support Google Maps autocomplete (JS) with Places library.
Autocomplete functionality works if the target input text element loads initially with the page; however, when I dynamically load it later (as part of a click event) ($(element).html('<input type="text" id="location" />');) the autocomplete doesn't work.
I've tried to reinitialize the initAutocomplete by calling the function again after loading the new "location" element (initAutocomplete()), but still not working. Is it possible to reinitialize initAutocomplete() for a dynamically generated autocomplete target (<input type="text" id="location" />)?
var placeSearch, autocomplete;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initAutocomplete() {
// Create the autocomplete object, restricting the search to geographical
// location types.
autocomplete = new google.maps.places.Autocomplete(
/** #type {!HTMLInputElement} */(document.getElementById('location')),
{types: ['geocode']});
// When the user selects an address from the dropdown, populate the address
// fields in the form.
autocomplete.addListener('place_changed', fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
document.getElementById("lat").value = place.geometry.location.lat();
document.getElementById("lng").value = place.geometry.location.lng();
}
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
autocomplete.setBounds(circle.getBounds());
});
}
}

How can I obtain the "latitude and longitude" of the selected place with Google Maps API?

I am trying to use Google Maps API service to allow my site visitors to type in their address in a box. Once he/she selects a matching address, I want to obtain the latitude and longitude info about the provided address.
Using the code in the API documentation, I got a map and a text box on my site. However, once Google finds a matching address I need to get the latitude and longitude info for the selected address only.
Here is the function that initialize the map
function initMap() {
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement, {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 6
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map
});
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// 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();
console.log(places);
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
/*
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
*/
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
//icon: icon,
title: place.name,
position: place.geometry.location
}));
//coords.latitude
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
console.log(latitude, longitude);
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
The following lines of code gave me the info that I am looking for. However, it seems that it display's it more that once (possibly it is displaying the info for multiple addresses). How can I get the latitude and longitude info only one address?
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
I tried adding a click listener where I Can grab the info one the lick event like this
map.addListener("click", function (event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
console.log(lat, lng);
});
However, this gives me the latitude and longitude of the place where I click on the map, not the address that I selected from the text box after the autocomplete suggested the matching addresses
I'm sure there is an easier way but I use maps.google.com and right-click wherever I want to find the coordinates for and choose what's here?, then the longitude and latitude will appear at the bottom of the map.
Using the Google's API you can just send an AJAX request, you don't need a map on your page to get coordinates. Check this out!
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY
var responseAsObject;
$("#div").load( "url", function( response, status, xhr ) {
responseAsObject = $.parseJSON(response);
});
var long = responseAsObject.results.geometry.location.lng;
var lat = responseAsObject.results.geometry.location.lat;

How to populate a google maps autocomplete search result with custom options on an interactive map?

So I'm stuck on this - I'm working on building a site that shows activities near a user dependent on the location they input i.e. if I put in "Kent, London" or a postcode into the search box, it'll show an interactive map with pins and/or a list that details nearby activities - essentially a similar function to how Trivago shows hotels when you put in a location and you can view the list/show the map.
I've managed so far to get an autocomplete function working on-site by creating an input box and calling the Google Maps API like so:
<head>
...
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
...
</head>
<body>
...
<input id="searchTextField" type="text" size="50">
...
</body>
And then calling a JS function:
function initialize() {
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input);
}
google.maps.event.addDomListener(window, 'load', initialize);
However I don't know how to:
Get the search box to, upon a user hitting enter OR clicking the
"search" button, display a page with an interactive map - to be
honest I think this will be an onClick function or something along
the lines if someone can clarify and provide me with the correct
syntax on opening a new page with this?
On this new page - I would want the interactive map with the data displayed dependent on the location the user entered - I can
appreciate not all locations will work and I am not planning on
covering the entire nation - instead I want to start off with
one-two locations and list activities on a map dependent on them -
so if I enter "Kent" for example or even a postcode - how would I
get a map to display?
As for the activities themselves I know what activities I want to put in but what would be the correct way to input and call these in accordance to the above requirements? Would I need to create and then import them from a Database of some sort? Could these populate on the map as pins and when you click on the pins more information is displayed? Or as a list on the side or below the map?
Appreciate any help I can appreciate this is a complex question and in no way do I intend to do something on the scale of say Trivago - more of a super toned down version within the same spirit of their search.
You can try to start with the different sample code provided by Google Maps JavaScript API.
Here is the example code on how to use Place Autocomplete.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.8688, lng: 151.2195},
zoom: 13
});
var input = /** #type {!HTMLInputElement} */(
document.getElementById('pac-input'));
var types = document.getElementById('type-selector');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29)
});
autocomplete.addListener('place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setIcon(/** #type {google.maps.Icon} */({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35)
}));
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
infowindow.open(map, marker);
});
// Sets a listener on a radio button to change the filter type on Places
// Autocomplete.
function setupClickListener(id, types) {
var radioButton = document.getElementById(id);
radioButton.addEventListener('click', function() {
autocomplete.setTypes(types);
});
}
setupClickListener('changetype-all', []);
setupClickListener('changetype-address', ['address']);
setupClickListener('changetype-establishment', ['establishment']);
setupClickListener('changetype-geocode', ['geocode']);
}
Now, you can make this code as your starting point, then try to apply here the different function that you want your application do.

Get location address from Latitude and Longitude in google maps

I want after click on google map and getting Latitude and Longitude get location place from they and put it (address) in filed input#searchTextField. What do i do?
I tried as, but don't work for me:
DEMO: http://jsfiddle.net/DXkZJ/
<input id="searchTextField" type="text" size="50" style="text-align: left;width:357px;direction: ltr;">
<div id="map_canvas" style="height: 350px;width: 500px;margin: 0.6em;"></div>
$(function () {
var lat = 44.88623409320778,
lng = -87.86480712897173,
latlng = new google.maps.LatLng(lat, lng),
image = 'http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png';
//zoomControl: true,
//zoomControlOptions: google.maps.ZoomControlStyle.LARGE,
var mapOptions = {
center: new google.maps.LatLng(lat, lng),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: true,
panControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
},
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE,
position: google.maps.ControlPosition.TOP_left
}
},
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions),
marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input, {
types: ["geocode"]
});
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(autocomplete, 'place_changed', function (event) {
infowindow.close();
var place = autocomplete.getPlace();
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
moveMarker(place.name, place.geometry.location);
alert(place.name);
$('.MapLat').val(place.geometry.location.lat());
$('.MapLon').val(place.geometry.location.lng());
});
google.maps.event.addListener(map, 'click', function (event) {
$('.MapLat').val(event.latLng.lat());
$('.MapLon').val(event.latLng.lng());
alert(event.latLng.place.name)
});
$("#searchTextField").focusin(function () {
$(document).keypress(function (e) {
if (e.which == 13) {
return false;
infowindow.close();
var firstResult = $(".pac-container .pac-item:first").text();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
"address": firstResult
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var lat = results[0].geometry.location.lat(),
lng = results[0].geometry.location.lng(),
placeName = results[0].address_components[0].long_name,
latlng = new google.maps.LatLng(lat, lng);
moveMarker(placeName, latlng);
$("input").val(firstResult);
alert(firstResult)
}
});
}
});
});
function moveMarker(placeName, latlng) {
marker.setIcon(image);
marker.setPosition(latlng);
infowindow.setContent(placeName);
//infowindow.open(map, marker);
}
});​
Ok, so firstly you need reverse geocoding, not regular geocoding, because you are going from a latitude/longitude into an address rather than the other way around (see reference). Secondly your key listener would never do anything because it almost immediately states return false; in this case you probably want event.stopPropogation(). Furthermore google maps will intercept your mouse clicks at a greater depth in the DOM tree than document, so the event will never be listened that highly anyway.
So what I did was to change your geocode into a reverse geocode, as well as move the code in the document listener into the google listener. If you wanted to retain the behaviour of the listener being added on focus, you can simply create a new listener on the map object. Here is a working jsfiddle demonstrating these changes, hopefully this helps.
Take a look at the gmap developers api.
for topic Reverse Geocoding (Address Lookup) .
You will got your answer.
Just add this code after moveMarker() function
$("#map_canvas").click(function() {
$("#searchTextField").val($(".MapLat").val() +", "+$(".MapLon").val());
});
Hope, this is what you needed :)

Categories

Resources