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

基于坐标半径筛选JSON数据的方案优化咨询

基于坐标半径筛选JSON数据的方案优化咨询

嘿,你的思路其实已经能解决问题了,但确实有可以优化的地方,咱们一步步聊:

首先先说说你当前方案的小问题:

  • 你用±0.15的经纬度范围来筛选,本质上是在选一个矩形区域,不是真正的圆形半径范围——因为经纬度的距离在不同纬度是不一样的,比如赤道上1度经度≈111km,但到高纬度会变小,所以这个矩形其实和你想的“半径”不是一回事。
  • 代码里的inRange用法可以简化,比如判断纬度是否在[userLat-0.15, userLat+0.15]之间,不用写两次正负的判断,inRange(tot.latitude, userCoordinates.latitude - 0.15, userCoordinates.latitude + 0.15)就够了,经度同理,这样逻辑更清晰。
  • 用map来遍历数组有点浪费,map是用来转换数组元素的,筛选的话用Array.filter()更语义化,不用手动push到新数组。

那优化方案分两种情况:

情况1:不需要高精度的距离计算(比如前端快速筛选)

如果只是想快速做近似筛选,保持你的思路但简化代码:

import { inRange } from 'lodash';

const filterTotems = (userCoordinates) => {
  const { latitude: userLat, longitude: userLng } = userCoordinates;
  // 直接定义范围的上下限,不用写两次判断
  const filteredTot = totems.filter(tot => 
    inRange(tot.latitude, userLat - 0.15, userLat + 0.15) &&
    inRange(tot.longitude, userLng - 0.15, userLng + 0.15)
  );
  setFiltredTotems(filteredTot);
};

这样代码更简洁,语义也更明确。

情况2:需要真正的半径范围筛选(高精度)

如果要准确筛选出用户坐标X公里半径内的地点,就得用地理距离公式,最常用的是Haversine公式,计算两点之间的球面距离。不用依赖lodash,自己实现或者用简单的函数:

// 计算两点之间的距离(单位:公里)
const 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; // 距离(公里)
};

const filterTotems = (userCoordinates, radius = 10) => { // radius默认10公里
  const { latitude: userLat, longitude: userLng } = userCoordinates;
  const filteredTot = totems.filter(tot => 
    calculateDistance(userLat, userLng, tot.latitude, tot.longitude) <= radius
  );
  setFiltredTotems(filteredTot);
};

这个方法的优势是精准,不管用户在哪个纬度,筛选的都是真正的圆形半径范围,适合对距离精度有要求的场景。

额外小建议

  • 如果你的totems数据量很大(比如上千条),前端筛选可能会有点卡,这时候最好把筛选逻辑放到后端,用数据库的地理索引(比如PostGIS、MongoDB的地理查询),性能会好很多。
  • 如果你还是想用lodash,也可以把范围判断封装成一个小函数,让代码更干净。

总的来说,你的初始方案是可行的,但根据需求选择更合适的方法会更好~

备注:内容来源于stack exchange,提问作者Jorge Fabris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 10:09:09