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

如何根据经纬度筛选下拉列表,实现邮编对应最近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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 02:42:03