Spaces:
Sleeping
Sleeping
| import Foundation | |
| import Vapor | |
| struct DemController { | |
| struct Query: Content { | |
| let latitude: [String] | |
| let longitude: [String] | |
| let apikey: String? | |
| func validate() throws -> (latitude: [Float], longitude: [Float]) { | |
| let latitude = try Float.load(commaSeparated: self.latitude) | |
| let longitude = try Float.load(commaSeparated: self.longitude) | |
| guard latitude.count == longitude.count else { | |
| throw ForecastapiError.latitudeAndLongitudeSameCount | |
| } | |
| guard !latitude.isEmpty else { | |
| throw ForecastapiError.latitudeAndLongitudeNotEmpty | |
| } | |
| guard latitude.count <= 100 else { | |
| throw ForecastapiError.latitudeAndLongitudeMaximum(max: 100) | |
| } | |
| try zip(latitude, longitude).forEach { (latitude, longitude) in | |
| if latitude > 90 || latitude < -90 || latitude.isNaN { | |
| throw ForecastapiError.latitudeMustBeInRangeOfMinus90to90(given: latitude) | |
| } | |
| if longitude > 180 || longitude < -180 || longitude.isNaN { | |
| throw ForecastapiError.longitudeMustBeInRangeOfMinus180to180(given: longitude) | |
| } | |
| } | |
| return (latitude, longitude) | |
| } | |
| } | |
| func query(_ req: Request) async throws -> Response { | |
| try await req.ensureSubdomain("api") | |
| let params = req.method == .POST ? try req.content.decode(Query.self) : try req.query.decode(Query.self) | |
| let keyCheck = try await req.ensureApiKey("api", apikey: params.apikey) | |
| let (latitude, longitude) = try params.validate() | |
| await req.incrementRateLimiter(weight: 1, apikey: keyCheck.apikey) | |
| // Run query on separat thread pool to not block the main pool | |
| return try await ForecastapiController.runLoop.next().submit({ | |
| let elevation = try zip(latitude, longitude).map { (latitude, longitude) in | |
| try Dem90.read(lat: latitude, lon: longitude) | |
| } | |
| var headers = HTTPHeaders() | |
| headers.add(name: .contentType, value: "application/json") | |
| return Response(status: .ok, headers: headers, body: .init(string: """ | |
| {"elevation":\(elevation)} | |
| """)) | |
| }).get() | |
| } | |
| } | |