You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Places API地点预测排序规则及控制方法咨询

问题解答:Google Places API机场预测排序规则与自定义排序实现

一、Autocomplete机场结果的默认排序规则

Google Places Autocomplete的结果排序逻辑并未完全公开,实际是综合以下因素的加权算法:

  • 搜索词匹配度:机场名称、IATA代码与输入关键词的匹配程度
  • 机场权重:机场的运营规模、旅客吞吐量(大型枢纽机场优先级更高,比如伦敦希思罗会排在伦敦城市机场之前)
  • 位置相关性:若用户开启定位,会优先返回靠近用户当前位置的结果,但仅输入城市名称时,该因素权重较低
  • Google内部数据权重:包括搜索热度、商户信息完整性等

官方文档未明确该排序逻辑的具体细节,因此无法直接通过API参数调整默认排序。

二、实现按「距离目标城市由近到远」排序的方法

要实现自定义距离排序,需要手动完成以下步骤:

  1. 获取目标城市的经纬度坐标
  2. 对每个机场预测结果调用PlacesService.getDetails获取机场的经纬度
  3. 计算机场与目标城市的直线距离
  4. 按距离排序后渲染结果

修改后的代码示例

function initAutocomplete() {
    var autoComplete = new google.maps.places.Autocomplete(
        document.getElementById('cityTown'),{types: ['geocode']}
    );

    google.maps.event.addListener(autoComplete, 'place_changed', () => {
        this.location.loc = autoComplete.getPlace();
        $.each(this.location.loc.address_components, function(key,value) {
            if(value.types.includes('country,political')){               
                document.getElementById('country__c').value= value.long_name;
            }
        });
        // 选择城市后直接调用机场搜索,传入城市经纬度
        getAirports(autoComplete.getPlace().name, autoComplete.getPlace().geometry.location);
    });
}

// 计算两点间直线距离(Haversine公式)
function calculateDistance(lat1, lon1, lat2, lon2) {
    const R = 6371; // 地球半径(公里)
    const dLat = (lat2 - lat1) * Math.PI / 180;
    const dLon = (lon2 - lon1) * Math.PI / 180;
    const a = 
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 
        Math.sin(dLon/2) * Math.sin(dLon/2); 
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    return R * c; // 返回公里数
}

function getAirports(cityName, cityLatLng){
    const autoCompleteAirport = new google.maps.places.AutocompleteService();
    const suggestionsList = document.getElementById('suggestions');
    const placesService = new google.maps.places.PlacesService(document.createElement('div')); // 需传入DOM元素

    autoCompleteAirport.getPlacePredictions({ input: cityName, types: ['airport'] }, (predictions, status) => {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            // 存储带距离的机场数据
            const airportWithDistance = [];

            predictions.forEach((prediction) => {
                // 调用getDetails获取机场经纬度
                placesService.getDetails({ placeId: prediction.place_id }, (place, detailStatus) => {
                    if (detailStatus === google.maps.places.PlacesServiceStatus.OK) {
                        const airportLatLng = place.geometry.location;
                        const distance = calculateDistance(
                            cityLatLng.lat(), cityLatLng.lng(),
                            airportLatLng.lat(), airportLatLng.lng()
                        );
                        airportWithDistance.push({
                            description: prediction.description,
                            distance: distance
                        });

                        // 所有机场数据获取完成后排序渲染
                        if (airportWithDistance.length === predictions.length) {
                            airportWithDistance.sort((a, b) => a.distance - b.distance);
                            suggestionsList.innerHTML = '';
                            airportWithDistance.forEach(item => {
                                const suggestion = document.createElement('li');
                                suggestion.textContent = `${item.description} (距离: ${item.distance.toFixed(1)}公里)`;
                                suggestionsList.appendChild(suggestion);
                            });
                        }
                    }
                });
            });
        }
    });
}

// 初始化调用(若有预设城市,需先获取该城市的经纬度)
var city='London'; 
// 预设城市时,先通过Geocoding API获取经纬度
if(city!=''){ 
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({ address: city }, (results, status) => {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            setTimeout(() => getAirports(city, results[0].geometry.location), 5000);
        } else {
            alert('无法获取城市位置');
        }
    });
}else{
    alert('No city found');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js?libraries=places&callback=initAutocomplete&key=API_KEY"></script>

<h2>Results from Places API</h2>
<ul id="suggestions"></ul>

关键修改说明

  • 修复了setTimeout的调用错误:原代码setTimeout(getAirports(city), 5000)会立即执行函数,改为箭头函数实现延迟调用
  • 新增calculateDistance函数,使用Haversine公式计算两点间直线距离
  • 通过PlacesService.getDetails获取每个机场的经纬度坐标
  • 收集所有机场数据后按距离排序,再渲染结果
  • 预设城市时,先通过Geocoding API获取城市经纬度,确保距离计算的准确性

注意事项

  • 调用getDetails会额外消耗API配额,需注意成本控制
  • 若机场数量较多,可考虑加入防抖或通过getPlacePredictions的radius参数缩小搜索范围

内容的提问来源于stack exchange,提问作者AdamJones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:25:32