package mlgpx

  1. Overview
  2. Docs

Source file coordinate.ml

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
(** Geographic coordinate types with validation *)

(** Private coordinate types with validation constraints *)
type latitude = private float
type longitude = private float  
type degrees = private float

(** Coordinate pair - main type for this module *)
type t = {
  lat : latitude;
  lon : longitude;
}

(** Smart constructors for validated coordinates *)
let latitude f =
  if f >= -90.0 && f <= 90.0 then Ok (Obj.magic f : latitude)
  else Error (Printf.sprintf "Invalid latitude: %f (must be between -90.0 and 90.0)" f)

let longitude f =
  if f >= -180.0 && f < 180.0 then Ok (Obj.magic f : longitude)
  else Error (Printf.sprintf "Invalid longitude: %f (must be between -180.0 and 180.0)" f)

let degrees f =
  if f >= 0.0 && f < 360.0 then Ok (Obj.magic f : degrees)
  else Error (Printf.sprintf "Invalid degrees: %f (must be between 0.0 and 360.0)" f)

(** Convert back to float *)
let latitude_to_float (lat : latitude) = (lat :> float)
let longitude_to_float (lon : longitude) = (lon :> float)
let degrees_to_float (deg : degrees) = (deg :> float)

(** Create coordinate pair *)
let make lat lon = { lat; lon }

(** Create coordinate pair from floats with validation *)
let make_from_floats lat_f lon_f =
  match latitude lat_f, longitude lon_f with
  | Ok lat, Ok lon -> Ok { lat; lon }
  | Error e, _ | _, Error e -> Error e

(** Extract components *)
let lat t = t.lat
let lon t = t.lon
let to_floats t = (latitude_to_float t.lat, longitude_to_float t.lon)

(** Compare coordinates *)
let compare t1 t2 =
  let lat_cmp = Float.compare (latitude_to_float t1.lat) (latitude_to_float t2.lat) in
  if lat_cmp <> 0 then lat_cmp
  else Float.compare (longitude_to_float t1.lon) (longitude_to_float t2.lon)

(** Equality *)
let equal t1 t2 = compare t1 t2 = 0

(** Pretty printer *)
let pp ppf t =
  Format.fprintf ppf "(%g, %g)" 
    (latitude_to_float t.lat) 
    (longitude_to_float t.lon)
OCaml

Innovation. Community. Security.