4 people like it.
Like the snippet!
Finding nearest airplane to a location
Given a location as a float tuple (latitude, longitude) it will return the plane closest nearby as a JsonValue using the OpenSky API. For fun also demonstrating some operator overloading with (-->) between two coordinates. I'm new to these functional languages, so please feel free to update the solution with interesting refactortings and whatnot.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
|
#r "FSharp.Data.dll"
open System
open FSharp.Data
let distanceFromLocation (lat1,lon1) (lat2,lon2) =
let deg2rad deg = deg * (Math.PI/180.)
let R = 6371.
let (dLat,dLon) = deg2rad (abs (lat1-lat2)), deg2rad (abs(lon1-lon2))
let a =
(sin(dLat / 2.)) * (sin(dLat / 2.)) +
(cos(deg2rad(lat1))) * (cos(deg2rad(lat2))) *
(sin(dLon/2.)) * (sin(dLon/2.))
R * (2. * (atan2 (sqrt a) (sqrt (1. - a))))
let nearestPlane destination : JsonValue =
let aeroJSON = "https://opensky-network.org/api/states/all"
let json = JsonValue.Load(aeroJSON)
let validTuple (i,j) = i <> JsonValue.Null && j <> JsonValue.Null
let parseTuple (i:JsonValue,j:JsonValue) = (i.AsFloat(), j.AsFloat())
let n = Array.length (json.["states"].AsArray())
let rec findPlane i recordPlane recordDistance =
if i = (n-1) then recordPlane
else
let state = json.["states"].[i]
let planeLoc = (state.[6], state.[5])
if validTuple planeLoc then
let distance = distanceFromLocation destination (parseTuple planeLoc)
if recordDistance > distance then
findPlane (i+1) state distance
else findPlane (i+1) recordPlane recordDistance
else findPlane (i+1) recordPlane recordDistance
findPlane 0 (JsonValue.Null) (1e99)
//Examples:
nearestPlane (51.507351, -0.127758) //-- London
nearestPlane (48.860731, 2.342342) //-- Paris
nearestPlane (35.708628, 139.731891) //-- Tokyo
|
namespace System
Multiple items
namespace FSharp
--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data
--------------------
namespace Microsoft.FSharp.Data
val distanceFromLocation : lat1:float * lon1:float -> lat2:float * lon2:float -> float
Full name: Script.distanceFromLocation
val lat1 : float
val lon1 : float
val lat2 : float
val lon2 : float
val deg2rad : (float -> float)
val deg : float
type Math =
static val PI : float
static val E : float
static member Abs : value:sbyte -> sbyte + 6 overloads
static member Acos : d:float -> float
static member Asin : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member BigMul : a:int * b:int -> int64
static member Ceiling : d:decimal -> decimal + 1 overload
static member Cos : d:float -> float
...
Full name: System.Math
field Math.PI = 3.14159265359
val R : float
val dLat : float
val dLon : float
val abs : value:'T -> 'T (requires member Abs)
Full name: Microsoft.FSharp.Core.Operators.abs
val a : float
val sin : value:'T -> 'T (requires member Sin)
Full name: Microsoft.FSharp.Core.Operators.sin
val cos : value:'T -> 'T (requires member Cos)
Full name: Microsoft.FSharp.Core.Operators.cos
val atan2 : y:'T1 -> x:'T1 -> 'T2 (requires member Atan2)
Full name: Microsoft.FSharp.Core.Operators.atan2
val sqrt : value:'T -> 'U (requires member Sqrt)
Full name: Microsoft.FSharp.Core.Operators.sqrt
val nearestPlane : float * float -> JsonValue
Full name: Script.nearestPlane
val destination : float * float
type JsonValue =
| String of string
| Number of decimal
| Float of float
| Record of properties: (string * JsonValue) []
| Array of elements: JsonValue []
| Boolean of bool
| Null
member Request : uri:string * ?httpMethod:string * ?headers:seq<string * string> -> HttpResponse
member RequestAsync : uri:string * ?httpMethod:string * ?headers:seq<string * string> -> Async<HttpResponse>
override ToString : unit -> string
member ToString : saveOptions:JsonSaveOptions -> string
member WriteTo : w:TextWriter * saveOptions:JsonSaveOptions -> unit
static member AsyncLoad : uri:string * ?cultureInfo:CultureInfo -> Async<JsonValue>
static member private JsonStringEncodeTo : w:TextWriter -> value:string -> unit
static member Load : uri:string * ?cultureInfo:CultureInfo -> JsonValue
static member Load : reader:TextReader * ?cultureInfo:CultureInfo -> JsonValue
static member Load : stream:Stream * ?cultureInfo:CultureInfo -> JsonValue
static member Parse : text:string * ?cultureInfo:CultureInfo -> JsonValue
static member ParseMultiple : text:string * ?cultureInfo:CultureInfo -> seq<JsonValue>
static member ParseSample : text:string * ?cultureInfo:CultureInfo -> JsonValue
Full name: FSharp.Data.JsonValue
val aeroJSON : string
val json : JsonValue
static member JsonValue.Load : uri:string * ?cultureInfo:Globalization.CultureInfo -> JsonValue
static member JsonValue.Load : reader:IO.TextReader * ?cultureInfo:Globalization.CultureInfo -> JsonValue
static member JsonValue.Load : stream:IO.Stream * ?cultureInfo:Globalization.CultureInfo -> JsonValue
val validTuple : (JsonValue * JsonValue -> bool)
val i : JsonValue
val j : JsonValue
union case JsonValue.Null: JsonValue
val parseTuple : (JsonValue * JsonValue -> float * float)
static member JsonExtensions.AsFloat : x:JsonValue * ?cultureInfo:Globalization.CultureInfo * ?missingValues:string [] -> float
val n : int
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val length : array:'T [] -> int
Full name: Microsoft.FSharp.Collections.Array.length
val findPlane : (int -> JsonValue -> float -> JsonValue)
val i : int
val recordPlane : JsonValue
val recordDistance : float
val state : JsonValue
val planeLoc : JsonValue * JsonValue
val distance : float
More information