计算蒸气中的距离4

Calculating distance in vapor4

我现在尝试输入一个 longitudelatitude 和 return 一个 Pers 模型,如果距离小于(任意数字) ) 米。而且我知道 CLLocation 在这里是一个不好的用法,但它并没有想出 postgis 的任何想法。所以在这种情况下,我只有下面的控制器,我想我应该在 return 过滤器中编写一些代码。但我实际上不知道在过滤器内部做什么才能使编译通过。

控制器:

import Foundation
import Vapor
import Fluent
import CoreLocation

final class InformationController{
    func temp(_ req:Request) throws -> EventLoopFuture<[Pers]> {
  
        let userlocation = try req.content.decode(Pers.UserLocation.self)
        
        let mylocation = CLLocation(latitude: userlocation.latitude, longitude: userlocation.lonitude)
        
        let pers = try req.content.decode([Pers].self)
        
        let newUsers = pers.filter{ user in
            let location = CLLocation(latitude: user.latitude, longitude: user.longitude)
            return location.distance(from: mylocation) < 100
                
        }
        
        return Pers.query(on: req.db).filter().all()
        
    }

}

Pers 型号:

import Foundation
import Fluent
import Vapor
import FluentPostgresDriver


final class Pers:Model,Content{
    static let schema = "people"
    
    @ID(key: .id)
    var id:UUID?
    
    @Field(key: "姓名")
    var name: String
    
    @Field(key: "IG帳號")
    var account: String
    
    @Field(key: "頭像")
    var picture: String
    
    @Field(key: "年紀")
    var age: String
    
    @Field(key: "生日")
    var birth: String
    
    @Field(key:"緯度")
    var latitude: Double
    
    @Field(key:"經度")
    var longitude: Double
    
    @Field(key: "居住城市")
    var city: String
    
    @Field(key: "興趣")
    var hobby : String
    
    @Parent(key: "user_id")
    var user: User

    init(){}
    
    init(id:UUID?=nil, name:String, account:String, picture:String ,age:String, birth:String,latitude: Double, longitude: Double, city:String, hobby:String, userId:UUID){
        self.id=id
        self.name=name
        self.account=account
        self.picture=picture
        self.age=age
        self.birth=birth
        self.latitude = latitude
        self.longitude = longitude
        self.city=city
        self.hobby=hobby
        self.$user.id=userId
    }
}

extension Pers{
    struct UserLocation: Content {
        var latitude: Double
        var lonitude: Double
    }
}

您的直接问题的答案是 return newUsers,如图所示更改路线的 return 类型,但我也会使用类似的方式解码:

struct LocData: Decodable {
    let userLocation: Pers.UserLocation
    let pers: [Pers]
}

func temp(_ req:Request) throws -> [Pers] {
    let locData = try req.content.decode(LocData.self)
    let userlocation = locData.userLocation
    let mylocation = CLLocation(latitude: userlocation.latitude, longitude: userlocation.longitude)
        
    return locData.pers.filter{ user in
        let location = CLLocation(latitude: user.latitude, longitude: user.longitude)
        return location.distance(from: mylocation) < 100  
    }
}

您的 JSON 需要看起来像:

{ "userLocation" : { ... },
  "pers" : [ ... ]
}

您的后续问题是您正试图以两种不同的方式解码请求数据。第一个有效,但第二个失败。您只为示例图像中的第一个解码提供 JSON 数据,因此第二个解码没有数组。

更根本的问题是,您确实应该在客户端执行此操作,因为您必须拥有所需的所有源数据才能将其发送到服务器。将可能很大的数据集传输到仅对 return(的子集)相同数据集作为响应进行简单、独立的计算是没有意义的。有关所需计算的示例实现,请参阅 How to find my distance to a known location in JavaScript