Google Maps API V3 - Невозможно геокодировать предсказания AutocompleteService

Я использую google.maps.places.AutocompleteService для получения предложений по поиску мест, но я не могу геокодировать некоторые из прогнозов.

Пример этого: когда я ищу "устья устья бурь", одно из предсказаний, которые я возвращаю, это "лагерь отдыха в бухте рек в Южной Африке", но этот адрес не может быть привязан к геодезическому, чтобы получить решетку/долготу, например: http://maps.googleapis.com/maps/api/geocode/json?address=Storms%20River%20Mouth%20Rest%20Camp,%20South%20Africa&sensor=true

Есть ли способ получить значения высоты/долготы для предсказаний автозаполнения?

В качестве альтернативы, я не понимаю, почему автозаполнение google возвращает предсказания, которые невозможно геокодировать.

Вот базовый пример логики и кода, с которыми я работаю:

var geocoder = new google.maps.Geocoder();
var service = new google.maps.places.AutocompleteService(null, {
 types: ['geocode'] 
});
service.getQueryPredictions({ input: query }, function(predictions, status) {
 // Show the predictions in the UI
 showInAutoComplete(predictions);
};
// When the user selects an address from the autcomplete list
function onSelectAddress(address) {
 geocoder.geocode({ address: address }, function(results, status) {
 if (status !== google.maps.GeocoderStatus.OK) {
 // This shouldn't never happen, but it does
 window.alert('Location was not found.');
 }
 // Now I can get the location of the address from the results
 // eg: results[0].geometry.location
 });
}

[edit] - Просмотрите рабочий пример здесь: http://demos.badsyntax.co/places-search-bootstrap/example.html

6 ответов

Используйте getPlacePredictions() вместо getQueryPredictions(). Это вернет reference для места, которое вы можете использовать для извлечения деталей, используя placesService.getDetails(). Детали будут содержать геометрию для места.

Примечание: placesService - это объект google.maps.places.PlacesService.


Вот код, который я написал, вдохновленный @Dr.Molle

function initializePlaces(q) {
 googleAutocompleteService = new google.maps.places.AutocompleteService(); 
 if(q){
 googleAutocompleteService.getPlacePredictions({
 input: q
 }, callbackPlaces);
 }else { //no value entered loop }
 }
 function callbackPlaces(predictions, status) {
 if (status != google.maps.places.PlacesServiceStatus.OK) {
 alert(status);
 return;
 }
 for (var i = 0; i < predictions.length; i++) {
 googlePlacesService = new google.maps.places.PlacesService(document.getElementById("q"));
 googlePlacesService.getDetails({
 reference: predictions[i].reference
 }, function(details, status){
 if(details){
 console.log(details.geometry.location.toString());
 }
 });
 console.log(predictions[i].description);
 }
 };
 google.maps.event.addDomListener(window, 'load', initializePlaces);
 $(document).on('*****', 'input#q', function(e){
 initializePlaces($(this).val());
 });

Проблема, которую я вижу, - это новый объект PlacesService при каждом нажатии клавиши, который может быть излишним - я не знаю, как работать, хотя.

Проводя его здесь, если кто-то ищет его.


Попробуйте следующее:

function onSelectAddress(address, callback) {
 var geocoder = new google.maps.Geocoder();
 geocoder.geocode({'address': address}, function(results, status) {
 if (status == google.maps.GeocoderStatus.OK) {
 callback(results[0].geometry.location);
 } else {
 alert("Can't find address: " + status);
 callback(null);
 }
 });
}

Затем вызов и обратный вызов:

onSelectAddress('your address here', function(location){
//Do something with location
if (location)
 alert(location);
});

Извините за мой английский. У меня есть вопрос для вас: Можете ли вы показать мне метод showInAutoComplete()??? Я показываю прогнозы в списке href, но я не знаю, как сохранить значение "clicked".


Предсказания, возвращаемые AutocompleteService, имеют свойство PlaceId. Вы можете передать PlaceId вместо адреса геокодеру в соответствии с документацией https://developers.google.com/maps/documentation/javascript/geocoding.

var service = new google.maps.places.AutocompleteService();
var request = { input: 'storms river mouth' };
service.getPlacePredictions(request, function (predictions, status) {
 if(status=='OK'){
 geocoder.geocode({ 
 'placeId': predictions[0].place_id
 }, 
 function(responses, status) {
 if (status == 'OK') {
 var lat = responses[0].geometry.location.lat();
 var lng = responses[0].geometry.location.lng();
 console.log(lat, lng);
 }
 });
 }
});


Если вам нужно вернуть все результаты сразу в правильном порядке, используйте это:

var service = new google.maps.places.AutocompleteService();
service.getPlacePredictions({
 input: '*** YOUR QUERY ***'
}, function(predictions, status) {
 var data = [];
 if (status != google.maps.places.PlacesServiceStatus.OK) {
 console.error(status);
 processResults(data);
 return;
 }
 var s = new google.maps.places.PlacesService(document.createElement('span'));
 var l = predictions.length;
 for (var i = 0, prediction; prediction = predictions[i]; i++) {
 (function(i) {
 s.getDetails(
 {
 reference: prediction.reference
 },
 function (details, status) {
 if (status == google.maps.places.PlacesServiceStatus.OK) {
 data[i] = details;
 } else {
 data[i] = null;
 }
 if (data.length == l) {
 processResults(data);
 }
 }
 );
 })(i);
 } });
function processResults(data) {
 console.log(data);
}


Возможно, это могло бы помочь вам.

var autocomplete = new google.maps.places.Autocomplete(this.input);
 //this.input is the node the AutocompleteService bindTo
 autocomplete.bindTo('bounds', this.map);
 //this.map is the map which has been instantiated
 google.maps.event.addListener(autocomplete, 'place_changed', function() {
 var place = autocomplete.getPlace();
 //then get lattude and longitude
 console.log(place.geometry.location.lat());
 console.log(place.geometry.location.lng());
 }

licensed under cc by-sa 3.0 with attribution.