Reputation: 651
I'm trying to get latitude and longitude from Autocomplete Google Maps API without showing the map. In my script autocompletion works well, but I can't get the latitude and longitude.
<script type="text/javascript">
function initialize() {
var options = {
types: ['(cities)']
};
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
google.maps.event.addDomListener(window, 'load', initialize);
var geocoder = new google.maps.Geocoder();
var address = autocomplete;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
alert(latitude);
}
});
</script>
Upvotes: 65
Views: 141509
Reputation: 2223
Google for some reason under "optimizations" recommends using their geocode service instead of Text Search. I'll have to answer the rest of the stackoverflow questions related to this. The provided code uses webservice since I was writing a react-native application, but you can easily adapt it.
const GOOGLE_MAPS_BASE = 'https://maps.googleapis.com/maps/api';
const GOOGLE_MAPS_API_KEY = 'https://console.cloud.google.com/apis/credentials';
// example code, remember to add error handling for your code
async function searchAndGetCoordExample() {
const results = await placeSearch('Fiera Capital Toronto');
const coordinates = [results[0].geometry.location.lat, results[0].geometry.location.lng];
}
export async function placeSearch({ query, language = 'en', limit = 10, lat, lon } = {}) {
/*
https://developers.google.com/maps/documentation/places/web-service/search-text
*/
const locationParam = (lat !== undefined && lon !== undefined) ? `&location=${lat},${lon}` : '';
const params = new URLSearchParams({
query,
language,
key: GOOGLE_MAPS_API_KEY,
});
return await fetchTimeout(`${GOOGLE_MAPS_BASE}/place/textsearch/json?input=${params.toString()}${locationParam}&key=${GOOGLE_MAPS_API_KEY}`).then(r => r.json());
}
async function fetchTimeout(resource, options = {}) {
// set timeout to 8 seconds from 300 seconds
// throws Timeout error (error.name === 'AbortError')
const { timeout = 8000 } = options;
options.headers = { 'User-Agent': 'MyApp', ...options.headers }
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
const response = await fetch(resource, {
...options,
signal: controller.signal
});
clearTimeout(id);
return response;
}
Upvotes: 1
Reputation: 1461
You can use the code below.
<script src="http://maps.googleapis.com/maps/api/js?libraries=places" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
document.getElementById('city2').value = place.name;
document.getElementById('cityLat').value = place.geometry.location.lat();
document.getElementById('cityLng').value = place.geometry.location.lng();
//alert("This function is working!");
//alert(place.name);
// alert(place.address_components[0].long_name);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
and this part is inside your form:
<input id="searchTextField" type="text" size="50" placeholder="Enter a location" autocomplete="on" runat="server" />
<input type="hidden" id="city2" name="city2" />
<input type="hidden" id="cityLat" name="cityLat" />
<input type="hidden" id="cityLng" name="cityLng" />
Upvotes: 146
Reputation: 179
<!DOCTYPE html>
<html>
<head>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async defer></script>
</head>
<body>
<input id="searchTextField" type="text" size="50" placeholder="Enter a location" autocomplete="on" runat="server" />
<input type="text" id="Lat" />
<input type="text" id="Lng" />
</body>
<script type="text/javascript">
function initialize() {
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
document.getElementById('Lat').value = place.geometry.location.lat();
document.getElementById('Lng').value = place.geometry.location.lng();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</html>
Upvotes: 0
Reputation: 7858
As per late 2020 this as easy as follows.
For the geometry
key to be presented on a place selected from the places dropdown, the field geometry
should be set on Autocomplete
object instance with setFields()
method.
The code should look like this.
Load the API library:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places&callback=initAutocomplete"
Init the autocomplete and process the selected place data generally same as other answers. But use autocomplete.setFields(['geometry'])
to get coordinates back;
let autocomplete;
// Init the autocomplete object
function initAutocomplete() {
autocomplete = new window.google.maps.places.Autocomplete(
document.getElementById('current_location'), { types: ["geocode"] }
);
// !!! This is where you set `geometry` field to be returned with the place.
autocomplete.setFields(['address_component', 'geometry']); // <--
autocomplete.addListener("place_changed", fillInAddress);
}
// Process the address selected by user
function fillInAddress() {
const place = autocomplete.getPlace();
// Here you can get your coordinates like this
console.log(place.geometry.location.lat());
console.log(place.geometry.location.lng());
}
See the Google API docs on Autocomplete.setFields
and geometry
option.
Upvotes: 8
Reputation: 541
Youtube video: https://youtu.be/8QYiGuq5LG4 This will help to to get lat/lon without showing the gmap.
<!DOCTYPE html>
<html>
<head>
<title>Place Autocomplete With Latitude & Longitude </title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
#pac-input {
background-color: #fff;
padding: 0 11px 0 13px;
width: 400px;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
text-overflow: ellipsis;
}
#pac-input:focus {
border-color: #4d90fe;
margin-left: -1px;
padding-left: 14px; /* Regular padding-left + 1. */
width: 401px;
}
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&key=[YOUR-KEY]"></script>
<script>
function initialize() {
var address = (document.getElementById('pac-input'));
var autocomplete = new google.maps.places.Autocomplete(address);
autocomplete.setTypes(['geocode']);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
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(' ');
}
/*********************************************************************/
/* var address contain your autocomplete address *********************/
/* place.geometry.location.lat() && place.geometry.location.lat() ****/
/* will be used for current address latitude and longitude************/
/*********************************************************************/
document.getElementById('lat').innerHTML = place.geometry.location.lat();
document.getElementById('long').innerHTML = place.geometry.location.lng();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<input id="pac-input" class="controls" type="text"
placeholder="Enter a location">
<div id="lat"></div>
<div id="long"></div>
</body>
</html>
Upvotes: 1
Reputation: 85
HTML:
<input type="text" id="address" name="address" value=""> //Autocomplete input address
<input type="hidden" name="s_latitude" id="s_latitude" value="" /> //get latitude
<input type="hidden" name="s_longitude" id="s_longitude" value="" /> //get longitude
Javascript:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places&callback=initMap"
async defer></script>
<script>
var input = document.getElementById('address');
var originLatitude = document.getElementById('s_latitude');
var originLongitude = document.getElementById('s_longitude');
var originAutocomplete = new google.maps.places.Autocomplete(input);
originAutocomplete.addListener('place_changed', function(event) {
var place = originAutocomplete.getPlace();
if (place.hasOwnProperty('place_id')) {
if (!place.geometry) {
// window.alert("Autocomplete's returned place contains no geometry");
return;
}
originLatitude.value = place.geometry.location.lat();
originLongitude.value = place.geometry.location.lng();
} else {
service.textSearch({
query: place.name
}, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
originLatitude.value = results[0].geometry.location.lat();
originLongitude.value = results[0].geometry.location.lng();
}
});
}
});
</script>
Upvotes: 0
Reputation: 51
You can get lat, lng from the place object i.e.
var place = autocomplete.getPlace();
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
Upvotes: 5
Reputation: 2379
Only need:
var place = autocomplete.getPlace();
// get lat
var lat = place.geometry.location.lat();
// get lng
var lng = place.geometry.location.lng();
Upvotes: 35
Reputation: 2976
Yes you can:
var place = autocomplete.getPlace();
document.getElementById('lat').value = place.geometry.location.lat();
document.getElementById('lon').value = place.geometry.location.lng();
Upvotes: 5
Reputation: 1641
You can get from the same api without any additional api or url call.
HTML
<input class="wd100" id="fromInput" type="text" name="grFrom" placeholder="From" required/>
Javascript
var input = document.getElementById('fromInput');
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-33.8902, 151.1759),
new google.maps.LatLng(-33.8474, 1512631)
)
var options = {
bounds: defaultBounds
}
var autocomplete = new google.maps.places.Autocomplete(input, options);
var searchBox = new google.maps.places.SearchBox(input, {
bounds: defaultBounds
});
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
console.log(places[0].geometry.location.G); // Get Latitude
console.log(places[0].geometry.location.K); // Get Longitude
//Additional information
console.log(places[0].formatted_address); // Formated Address of Place
console.log(places[0].name); // Name of Place
if (places.length == 0) {
return;
}
var bounds = new google.maps.LatLngBounds();
console.log(bounds);
});
}
Upvotes: 1
Reputation: 186
You can't get latitude/longitude from autocomplete API since the data generated by google from that API doesn't contain latitude and logitude field. Example:-
{
"predictions" : [
{
"description" : "IIT Mumbai, Mumbai, Maharashtra, India",
"id" : "ac3235cda973818a89b5fe21ad0f5261ac9b6723",
"matched_substrings" : [
{
"length" : 10,
"offset" : 0
}
],
"reference" : "CkQ0AAAAHWg-RSngiYHHdz_yqyFKmfSoBwT-_PW0k8qQDhsbiVrk7BlPHCyJb58OthledMUTGYS5Vhec1Zj2L7w9Rq0zDxIQrbn05RX1QgWHkSXsmTk1TRoU45APW2BBRIUsA3t6XBy_8s0BPPA",
"terms" : [
{
"offset" : 0,
"value" : "IIT Mumbai"
},
{
"offset" : 12,
"value" : "Mumbai"
},
{
"offset" : 20,
"value" : "Maharashtra"
},
{
"offset" : 33,
"value" : "India"
}
],
"types" : [ "establishment", "geocode" ]
}
],
"status" : "OK"
}
You can use the Google API to get the Longitude and Latitude from your address. As you already said, you should implement a hidden field where the result should be inserted. Then you can save the location together with the coordinates.
I recently implemented this function in one of my projects:
function getLatLngFromAddress(city, country){
var address = city +", "+ country;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$('#latitude').val(results[0].geometry.location.Pa);
$('#longitude').val(results[0].geometry.location.Qa);
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
Upvotes: 10
Reputation: 6158
Google Places API also provides REST api including Places Autocomplete. https://developers.google.com/places/documentation/autocomplete
But the data retrieve from the service must use for a map.
Upvotes: 1