GPS Exchange Format library/CLI in OCaml
at main 1.9 kB view raw
1(** Geographic coordinate types with validation *) 2 3(** Private coordinate types with validation constraints *) 4type latitude = private float 5type longitude = private float 6type degrees = private float 7 8(** Coordinate pair - main type for this module *) 9type t = { 10 lat : latitude; 11 lon : longitude; 12} 13 14(** Smart constructors for validated coordinates *) 15let latitude f = 16 if f >= -90.0 && f <= 90.0 then Ok (Obj.magic f : latitude) 17 else Error (Printf.sprintf "Invalid latitude: %f (must be between -90.0 and 90.0)" f) 18 19let longitude f = 20 if f >= -180.0 && f < 180.0 then Ok (Obj.magic f : longitude) 21 else Error (Printf.sprintf "Invalid longitude: %f (must be between -180.0 and 180.0)" f) 22 23let degrees f = 24 if f >= 0.0 && f < 360.0 then Ok (Obj.magic f : degrees) 25 else Error (Printf.sprintf "Invalid degrees: %f (must be between 0.0 and 360.0)" f) 26 27(** Convert back to float *) 28let latitude_to_float (lat : latitude) = (lat :> float) 29let longitude_to_float (lon : longitude) = (lon :> float) 30let degrees_to_float (deg : degrees) = (deg :> float) 31 32(** Create coordinate pair *) 33let make lat lon = { lat; lon } 34 35(** Create coordinate pair from floats with validation *) 36let make_from_floats lat_f lon_f = 37 match latitude lat_f, longitude lon_f with 38 | Ok lat, Ok lon -> Ok { lat; lon } 39 | Error e, _ | _, Error e -> Error e 40 41(** Extract components *) 42let lat t = t.lat 43let lon t = t.lon 44let to_floats t = (latitude_to_float t.lat, longitude_to_float t.lon) 45 46(** Compare coordinates *) 47let compare t1 t2 = 48 let lat_cmp = Float.compare (latitude_to_float t1.lat) (latitude_to_float t2.lat) in 49 if lat_cmp <> 0 then lat_cmp 50 else Float.compare (longitude_to_float t1.lon) (longitude_to_float t2.lon) 51 52(** Equality *) 53let equal t1 t2 = compare t1 t2 = 0 54 55(** Pretty printer *) 56let pp ppf t = 57 Format.fprintf ppf "(%g, %g)" 58 (latitude_to_float t.lat) 59 (longitude_to_float t.lon)