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

SwiftUI请求添加约束 Vapor后端实现10000米内Per数据过滤

实现方案

优先选择服务端过滤逻辑,避免全量拉取数据造成的带宽浪费、性能损耗,仅返回符合距离要求的数据。


1. 改造iOS端请求,传递当前坐标

将本地存储的经纬度作为查询参数传递给服务端,修改后的getlocation代码如下:

func getlocation(){
    let mylatitude = UserDefaults.standard.double(forKey:"mylatitude")
    let mylongitude = UserDefaults.standard.double(forKey: "mylongitude")
    // 拼接查询参数
    guard let url = URL(string: "http://127.0.0.1:8080/pers?lat=\(mylatitude)&lon=\(mylongitude)") else {
        fatalError("URL is not defined!")
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    URLSession.shared.dataTask(with: request) { (data, response, error) in
        do{
            if let data = data {
                // 服务端已经返回过滤后的结果,直接使用即可
                let result = try JSONDecoder().decode([Per].self, from: data)
                DispatchQueue.main.async {
                    self.per = result
                }
            }else{
                print("no data")
            }
        }catch(let error){
            print("error: ", error.localizedDescription)
        }
    }.resume()
}

2. 改造Vapor服务端逻辑

你使用的是PostgreSQL数据库,推荐安装postgis扩展实现高效的地理位置距离计算,也可以用球面距离公式实现过滤。

2.1 前置准备(可选,推荐)

给PostgreSQL对应数据库安装postgis扩展,执行SQL:

CREATE EXTENSION postgis;

2.2 修改Controller逻辑

修改InformationController的getall方法,接收坐标参数、做距离过滤:

import Foundation
import Vapor
import Fluent
final class InformationController{
    func getall (_ req: Request) throws -> EventLoopFuture<[Pers]>{
        // 接收请求传递的经纬度参数
        let userLat = try req.query.get(Double.self, at: "lat")
        let userLon = try req.query.get(Double.self, at: "lon")
        let maxDistance: Double = 10000 // 10000米
        // 用PostGIS的ST_DistanceSphere计算球面距离,单位为米
        return Pers.query(on: req.db)
            .filter(
                .sql(raw: "ST_DistanceSphere(ST_MakePoint(經度, 緯度), ST_MakePoint(\(userLon), \(userLat))) < \(maxDistance)")
            )
            .all()
    }
}

如果你不想安装postgis,也可以用Haversine公式实现距离计算,把上面的filter替换为:

.filter(.sql(raw: "6371000 * acos(cos(radians(\(userLat))) * cos(radians(緯度)) * cos(radians(經度) - radians(\(userLon))) + sin(radians(\(userLat))) * sin(radians(緯度))) < \(maxDistance)"))

2.3 路由无需修改

原有路由逻辑保持不变即可正常接收查询参数。


内容的提问来源于stack exchange,提问作者蔡濡安

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:27:03