谷歌地图API V3 - 无法对AutocompleteService预测进行地理编码

8
我正在使用google.maps.places.AutocompleteService来获取地点搜索的建议,但我无法对一些预测进行地理编码。
例如:当我搜索“storms river mouth”时,我会得到一个名为“Storms River Mouth Rest Camp,South Africa”的预测,但是这个地址无法进行地理编码以获取纬度/经度,例如: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
  });
}

[编辑] - 在此处查看一个工作示例:http://demos.badsyntax.co/places-search-bootstrap/example.html
6个回答

11

使用getPlacePredictions()替代getQueryPredictions()。这将返回一个reference地点,您可以使用placesService.getDetails()来检索详细信息。详细信息将包含该地点的几何信息。

注意:placesService是一个google.maps.places.PlacesService对象。


service.getPlacePredictions()不返回任何内容,并且它接受一个回调函数。在该回调函数中,我可以访问'predictions'和'status'参数。 - badsyntax
2
奇怪,当我按照我的无意义指令操作时,从getPlacePredictions获得了良好的结果:http://jsfiddle.net/doktormolle/mFgdw/ - Dr.Molle
谢谢!我完全不熟悉PlacesService。 - badsyntax
@Dr.Molle - 非常感谢您提供的示例代码 - 你太棒了,伙计! - foxybagga
你能提供一个在使用getPlacePredictions()的情况下使用getDetails()的例子吗? - zero_cool
显示剩余2条评论

8
AutocompleteService返回的预测结果具有"PlaceId"属性。根据文档https://developers.google.com/maps/documentation/javascript/geocoding,您可以将PlaceId传递给地理编码器,而不是地址。请注意保留HTML标记。
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);
            }
        });
    }
});

3

试试这个:

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列表上,但是我不知道如何保存“点击”的地址值。


非常感谢您指引我使用地理编码API,虽然我的问题有些不同,但这确实帮助我解决了它! - Romko

2

这是我写的代码,灵感来自@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('keyup', 'input#q', function(e){
        initializePlaces($(this).val());
    });

我看到的问题是每次按键都会创建一个新的PlacesService对象,这可能有点过度 - 虽然我不知道解决方法。
在这里发布以防有人需要。

你为什么在for循环中使用document.get(q)? - vipulsodha
1
还对如何使用getDetails()感兴趣。我认为你可以在循环外的一个地方初始化服务。 - zero_cool

1
如果您需要按正确顺序一次返回所有结果,请使用以下方法:
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);
}

-1

也许这可以帮助你。

 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());
 }

3
我不想使用google.maps.places.Autocomplete UI小部件,我想使用google.maps.places.AutocompleteService服务,并使用自己的自定义自动完成功能。 - badsyntax
你可以重写 .pac-container 和 .pac-item 的 CSS。 - Li Dian
1
他不打算使用自动完成用户界面。已经有其他问题/答案涵盖了这个方面。 - Raha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接