Google maps API V3 - 无法对 AutocompleteService 预测进行地理编码

Posted

技术标签:

【中文标题】Google maps API V3 - 无法对 AutocompleteService 预测进行地理编码【英文标题】:Google maps API V3 - Can't geocode AutocompleteService predictions 【发布时间】:2013-01-03 01:54:37 【问题描述】:

我正在使用 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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

service.getPlacePredictions() 不返回任何内容,它接受回调函数。在该回调函数中,我可以访问“predictions”和“status”参数。 你想要帮助还是想成为一个聪明的人。查看每个预测的参考成员,或者选择查看文档,然后您会看到在哪里可以找到参考。 我根本不想成为一个聪明的家伙。你的指示没有意义。 getPlacePredictions 不返回任何内容。我不知道该怎么说。也许我错过了什么?见这里:google-developers.appspot.com/maps/documentation/javascript/… 奇怪,当我遵循我毫无意义的指示时,我从 getPlacePredictions 得到了很好的结果:jsfiddle.net/doktormolle/mFgdw 谢谢!我对 PlacesService 完全不熟悉。【参考方案2】:

AutocompleteService 返回的预测具有 PlaceId 属性。您可以根据文档 https://developers.google.com/maps/documentation/javascript/geocoding 将 PlaceId 而不是地址传递给地理编码器。

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,我的问题有点不同,但它帮助我解决了它!【参考方案4】:

这是我编写的代码,灵感来自@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)? 也对如何使用getDetails()感兴趣。我认为您可以在循环外的一个地方初始化服务。【参考方案5】:

如果您需要以正确的顺序一次返回所有结果,请使用:

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

【讨论】:

【参考方案6】:

也许这对你有帮助。

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

【讨论】:

我不想使用google.maps.places.Autocomplete UI 小部件,我想使用google.maps.places.AutocompleteService 服务和我自己的自定义自动完成功能。 你可以重写.pac-container和.pac-item的css。 他不是在寻找使用自动完成 UI。还有其他问题/答案涵盖了这一点。

以上是关于Google maps API V3 - 无法对 AutocompleteService 预测进行地理编码的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***

Google Maps api V3 更新标记

Google Maps api v3 工具:视觉扭曲?

在 Google Maps V3 API 标记鼠标悬停时获取鼠标光标的位置

Google Maps API v3和fusion图层:获取行数据

地图加载后 Google Maps API v3 不会禁用滚轮