My agentic slop goes here. Not intended for anyone else!
at main 1.8 kB view raw
1(** Longitude module *) 2 3type t = float 4 5let normalize_180 f = 6 let x = mod_float (f +. 180.0) 360.0 in 7 if x < 0.0 then x +. 360.0 -. 180.0 8 else x -. 180.0 9 10let normalize_360 f = 11 let x = mod_float f 360.0 in 12 if x < 0.0 then x +. 360.0 else x 13 14let create f = normalize_180 f 15 16let unsafe_create f = f 17 18let of_dms ~degree ~minute ~second = 19 let sign = if degree < 0 || minute < 0 || second < 0.0 then -1.0 else 1.0 in 20 let d = abs degree in 21 let m = abs minute in 22 let s = abs_float second in 23 let decimal = float_of_int d +. (float_of_int m /. 60.0) +. (s /. 3600.0) in 24 create (sign *. decimal) 25 26let to_float t = t 27 28let to_range_180 t = normalize_180 t 29let to_range_360 t = normalize_360 t 30 31let degree t = int_of_float t 32 33let decimal_minute t = 34 let d = abs_float t in 35 (d -. floor d) *. 60.0 36 37let minute t = int_of_float (decimal_minute t) 38 39let second t = 40 let dm = decimal_minute t in 41 (dm -. floor dm) *. 60.0 42 43let hemisphere t = if t < 0.0 then `W else `E 44 45let add t delta = create (t +. delta) 46let sub t delta = create (t -. delta) 47let neg t = create (-.t) 48let abs t = abs_float t 49 50let equal a b = 51 (* Longitudes wrap around, so normalize before comparing *) 52 normalize_180 a = normalize_180 b 53 54let compare a b = Float.compare (normalize_180 a) (normalize_180 b) 55let ( = ) = equal 56let ( < ) a b = compare a b < 0 57let ( > ) a b = compare a b > 0 58let ( <= ) a b = compare a b <= 0 59let ( >= ) a b = compare a b >= 0 60 61let to_string t = Printf.sprintf "%.6f" t 62 63let format ?(precision = 6) t = 64 Printf.sprintf "%.*f" precision t 65 66let to_dms_string t = 67 let h = match hemisphere t with `E -> "E" | `W -> "W" in 68 let d = abs_float (float_of_int (degree t)) |> int_of_float in 69 let m = minute (abs_float t) in 70 let s = second (abs_float t) in 71 Printf.sprintf "%03d°%02d'%05.2f\"%s" d m s h