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

如何在Express+MongoDB中结合TomTom API筛选距离达标餐厅

筛选距离用户位置小于指定距离的餐厅

问题背景

我拥有一个餐厅集合,每个餐厅包含lat(纬度)和lon(经度)字段,前端会传入用户的位置信息,我使用TomTom Route API来计算距离。现有以下两个函数:

原计算距离函数

export const getDistance = async(res, mylat, mylong, lat, long) => {
  try {
    const distance = await axios.get(`https://api.tomtom.com/routing/1/calculateRoute/${mylat},${mylong}:${lat},${long}/json?key=${APIKEY}`)
    return res.status(200).json(position.data.routes[0].summary.lengthInMeters)
  } catch (error) {
      res.status(400).json({message: error.message})
  }
}

原获取餐厅函数

export const getRestaurants = async (req, res) => {
  try {
    const restaurants = await RestaurantModel.find()
    res.status(200).json(restaurants)
  } catch (error) {
    res.status(400).json({message: error.message})
  }
}

需求:如何使用getDistance()函数返回距离小于X米的餐厅?


解决方案

1. 重构getDistance函数

原函数直接向客户端返回响应,无法在其他逻辑中复用。我们需要修改它,让它返回计算出的距离数值(而非直接处理响应),同时修正原代码中变量名错误:

export const getDistance = async(mylat, mylong, lat, long) => {
  try {
    const response = await axios.get(`https://api.tomtom.com/routing/1/calculateRoute/${mylat},${mylong}:${lat},${long}/json?key=${APIKEY}`)
    // 修正原代码中position变量的错误,改为response
    return response.data.routes[0].summary.lengthInMeters
  } catch (error) {
    throw new Error(`计算距离失败: ${error.message}`)
  }
}

2. 修改餐厅查询函数,实现筛选逻辑

新建或修改原函数,让它接收用户位置和最大距离参数,筛选出符合条件的餐厅:

export const getRestaurantsWithinDistance = async (req, res) => {
  try {
    // 从请求参数中获取用户位置和最大距离
    const { mylat, mylong, maxDistance } = req.query
    if (!mylat || !mylong || !maxDistance) {
      return res.status(400).json({ message: '缺少必要参数:mylat、mylong、maxDistance' })
    }

    // 转换为数值类型
    const userLat = parseFloat(mylat)
    const userLon = parseFloat(mylong)
    const maxDist = parseFloat(maxDistance)

    // 获取所有餐厅数据
    const allRestaurants = await RestaurantModel.find()

    // 并行计算所有餐厅的距离,提高效率
    const filteredResults = await Promise.all(
      allRestaurants.map(async (restaurant) => {
        try {
          const distance = await getDistance(userLat, userLon, restaurant.lat, restaurant.lon)
          // 筛选距离小于等于指定值的餐厅,同时带上距离信息
          if (distance <= maxDist) {
            return { ...restaurant.toObject(), distance }
          }
          return null
        } catch (err) {
          console.error(`计算餐厅${restaurant._id}距离失败:`, err)
          return null
        }
      })
    )

    // 过滤掉计算失败或不符合条件的餐厅
    const validRestaurants = filteredResults.filter(Boolean)

    res.status(200).json(validRestaurants)
  } catch (error) {
    res.status(400).json({ message: error.message })
  }
}

关键说明

  • 并行计算:使用Promise.all并行处理所有餐厅的距离计算,比串行循环更高效
  • 参数校验:提前检查必要参数,避免后续逻辑出错
  • 容错处理:单个餐厅距离计算失败时,仅记录错误并跳过该餐厅,不影响整体结果
  • 增强返回数据:给符合条件的餐厅附加distance字段,方便前端直接使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:09:24