如何根据经纬度筛选下拉列表,实现邮编对应最近10个城市展示
实现经纬度筛选最近城市功能
你可以直接替换原有jQuery代码为以下版本,即可实现根据选中城市坐标筛选最近10个城市的需求:
$(function() { // 预先缓存下拉框的所有原始选项,避免过滤后丢失数据 const originalFilterOptions = $('#filter option').toArray(); // Haversine公式:计算两个经纬度点之间的距离,返回单位:公里 function getDistance(lat1, lng1, lat2, lng2) { const R = 6371; // 地球半径,单位公里 const dLat = (lat2 - lat1) * Math.PI / 180; const dLng = (lng2 - lng1) * 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(dLng/2) * Math.sin(dLng/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return R * c; } // 原有邮编输入查询逻辑,修复旧选项累加问题 $("#code_postal").keyup(function() { var zip_in = $(this); if (zip_in.val().length == 5) { // 先清空之前的datalist选项,避免重复 $("#output").empty(); // 发起请求 $.ajax({ url: "//api-adresse.data.gouv.fr/search/?q=" + zip_in.val() + "&type=municipality&limit=30", cache: false, dataType: "json", type: "GET", success: function(result) { const suggestions = []; for (let ii in result['features']) { const feature = result['features'][ii]; suggestions.push([ feature['properties']['name'], feature['geometry']['coordinates'][0], feature['geometry']['coordinates'][1] ]); } jQuery.each(suggestions, function(i, val) { $("#output").append(`<option value="${val[0]}" data-lat="${val[2]}" data-lng="${val[1]}">`); }); } }); } }); // 新增:城市选中后过滤下拉列表逻辑 $('#city').on('change', function() { const selectedCityName = $(this).val(); // 获取选中城市对应的经纬度 const selectedOption = $(`#output option[value="${selectedCityName}"]`); if (!selectedOption.length) return; const selectedLat = parseFloat(selectedOption.data('lat')); const selectedLng = parseFloat(selectedOption.data('lng')); if (isNaN(selectedLat) || isNaN(selectedLng)) return; // 遍历所有原始选项计算距离 const optionWithDistance = []; $(originalFilterOptions).each(function() { // 跳过默认的提示选项 if ($(this).val() === '0') return; const lat = parseFloat($(this).data('lat')); const lng = parseFloat($(this).data('lng')); if (isNaN(lat) || isNaN(lng)) return; const distance = getDistance(selectedLat, selectedLng, lat, lng); optionWithDistance.push({ element: this, distance: distance }); }); // 按距离从小到大排序,取前10个 const sortedOptions = optionWithDistance.sort((a,b) => a.distance - b.distance).slice(0,10); // 重新渲染下拉框,先加默认提示项 $('#filter').empty().append(originalFilterOptions[0]); // 再加排序后的10个选项 sortedOptions.forEach(item => { $('#filter').append(item.element); }); }); });
核心逻辑说明
- 页面加载时先缓存下拉框的所有原始选项,避免多次过滤后丢失原有数据
- 采用地理计算常用的Haversine公式计算两个经纬度点的地表距离,计算精度满足城市级筛选需求
- 监听城市输入框的选择事件,选中城市后自动读取对应经纬度,遍历所有可选城市计算距离,排序后取前10项更新下拉列表
- 修复了原有代码中多次输入邮编时datalist选项重复累加的问题
内容的提问来源于stack exchange,提问作者Creatz
相关产品推荐
相关产品推荐

