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

Webflow CMS+Leaflet实现按城市距离筛选房产及范围圈绘制需求

基于Leaflet的城市范围房源筛选与圈选实现方案

核心逻辑拆解

要实现目标功能,需完成三个关键环节:

  • 计算房源坐标与选定城市的球面距离(公里)
  • 在Leaflet地图上绘制对应半径的范围圈
  • 联动筛选房源元素与地图标记,仅保留圈内内容

1. 封装球面距离计算函数(Haversine公式)

Leaflet未直接提供公里级球面距离计算,用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; // 返回公里数
}

2. 绑定城市与距离选择器的事件监听

假设使用下拉框选择城市(#city-select)和输入框设置距离(#distance-input),将选择逻辑与地图、房源筛选联动:

// 全局变量存储地图实例和范围圈
let mapInstance;
let radiusCircle = null;

// DOM加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
  // 替换为你现有代码中初始化Leaflet地图的逻辑,获取map实例
  mapInstance = L.map(document.querySelector('[data-geo-map]')).setView([51.505, -0.09], 13);
  
  const citySelect = document.getElementById('city-select');
  const distanceInput = document.getElementById('distance-input');
  
  function handleFilterChange() {
    const selectedCity = citySelect.value; // 假设选项值为"lat,lng"格式坐标
    const maxDistance = parseFloat(distanceInput.value) || 0;
    
    if (!selectedCity || maxDistance <= 0) {
      resetFilter();
      return;
    }
    
    // 解析城市坐标
    const [cityLat, cityLng] = selectedCity.split(',').map(Number);
    
    // 绘制/更新范围圈
    updateRadiusCircle(cityLat, cityLng, maxDistance);
    
    // 筛选房源和标记
    filterPropertiesByDistance(cityLat, cityLng, maxDistance);
  }
  
  citySelect.addEventListener('change', handleFilterChange);
  distanceInput.addEventListener('input', handleFilterChange);
});

3. 绘制/更新范围圈

function updateRadiusCircle(cityLat, cityLng, maxDistance) {
  // 清除已有的范围圈
  if (radiusCircle) {
    mapInstance.removeLayer(radiusCircle);
  }
  
  // 公里转米(Leaflet的Circle默认单位是米)
  const radiusInMeters = maxDistance * 1000;
  
  // 绘制新范围圈
  radiusCircle = L.circle([cityLat, cityLng], {
    color: '#2563eb',
    fillColor: '#3b82f6',
    fillOpacity: 0.1,
    radius: radiusInMeters
  }).addTo(mapInstance);
  
  // 调整地图视野适配范围圈
  mapInstance.fitBounds(radiusCircle.getBounds());
}

4. 筛选圈内房源与地图标记

结合Webflow的data-geo-place和data-geo-coordinates属性,联动Finsweet筛选逻辑:

function filterPropertiesByDistance(cityLat, cityLng, maxDistance) {
  // 遍历所有房源元素
  document.querySelectorAll('[data-geo-place]').forEach(placeEl => {
    // 解析房源坐标
    const [placeLat, placeLng] = placeEl.dataset.geoCoordinates.split(',').map(Number);
    const distance = calculateDistance(cityLat, cityLng, placeLat, placeLng);
    
    // 控制房源显示/隐藏,匹配现有Finsweet筛选逻辑
    if (distance <= maxDistance) {
      placeEl.style.display = 'block';
      // 显示对应地图标记(需确保房源与标记通过data属性关联,如data-place-id)
      const markerId = placeEl.dataset.placeId;
      const marker = mapInstance._layers[markerId];
      if (marker) marker.addTo(mapInstance);
    } else {
      placeEl.style.display = 'none';
      const markerId = placeEl.dataset.placeId;
      const marker = mapInstance._layers[markerId];
      if (marker) mapInstance.removeLayer(marker);
    }
  });
  
  // 若需联动Finsweet筛选,可触发其更新事件(根据官方文档调整)
  // document.dispatchEvent(new CustomEvent('fs-cmsfilter-reset'));
}

// 重置筛选状态
function resetFilter() {
  if (radiusCircle) {
    mapInstance.removeLayer(radiusCircle);
    radiusCircle = null;
  }
  
  document.querySelectorAll('[data-geo-place]').forEach(placeEl => {
    placeEl.style.display = 'block';
    const markerId = placeEl.dataset.placeId;
    const marker = mapInstance._layers[markerId];
    if (marker) marker.addTo(mapInstance);
  });
}

关键注意事项

  • 确保data-geo-coordinates格式为纬度,经度(如51.505,-0.09),且数值有效
  • 房源元素与地图标记需通过唯一标识关联(如data-place-id),实现精准控制
  • 若Finsweet筛选有自定义样式逻辑,需调整显示/隐藏方式以兼容现有代码
  • 可根据UI需求修改范围圈的颜色、透明度等参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:45:52