package mlgpx
Library and CLI for parsing and generating GPS Exchange (GPX) formats
Install
dune-project
Dependency
Authors
Maintainers
Sources
mlgpx-1.0.0.tbz
md5=5342bb7e601273245a9fe263e5a08770
sha512=cd73b16e988b3ed3cc427a6c6c6d6c9c745adb1eb7efaae3c34e8d006e9c03d9f9d2616cd4118564bd9873903969d3e4053b585e79dbd3e3e7d0f541e2faac83
doc/src/mlgpx.core/route.ml.html
Source file route.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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
(** Route types and operations *) (** Route point is an alias for waypoint *) type point = Waypoint.t (** Main route type *) type t = { name : string option; cmt : string option; desc : string option; src : string option; links : Link.t list; number : int option; type_ : string option; extensions : Extension.t list; rtepts : point list; } (** {2 Route Operations} *) (** Create empty route *) let empty = { name = None; cmt = None; desc = None; src = None; links = []; number = None; type_ = None; extensions = []; rtepts = []; } (** Create route with name *) let make ~name = { empty with name = Some name } (** Create route from coordinate list *) let make_from_coords ~name coords = let make_rtept (lat_f, lon_f) = match Waypoint.make_from_floats ~lat:lat_f ~lon:lon_f () with | Ok wpt -> wpt | Error e -> invalid_arg e in let rtepts = List.map make_rtept coords in { empty with name = Some name; rtepts } (** Get route name *) let name t = t.name (** Get route description *) let description t = t.desc (** Get route number *) let number t = t.number (** Get route comment *) let comment t = t.cmt (** Get route source *) let source t = t.src (** Get route links *) let links t = t.links (** Get route type *) let type_ t = t.type_ (** Get route extensions *) let extensions t = t.extensions (** Get route points *) let points t = t.rtepts (** Get route point count *) let point_count t = List.length t.rtepts (** Clear all points *) let clear_points t = { t with rtepts = [] } (** Extract coordinates from route *) let to_coords t = List.map Waypoint.to_floats t.rtepts (** Simple great circle distance calculation *) let great_circle_distance lat1 lon1 lat2 lon2 = let deg_to_rad x = x *. Float.pi /. 180.0 in let lat1_rad = deg_to_rad lat1 in let lon1_rad = deg_to_rad lon1 in let lat2_rad = deg_to_rad lat2 in let lon2_rad = deg_to_rad lon2 in let dlat = lat2_rad -. lat1_rad in let dlon = lon2_rad -. lon1_rad in let a = sin (dlat /. 2.0) ** 2.0 +. cos lat1_rad *. cos lat2_rad *. sin (dlon /. 2.0) ** 2.0 in let c = 2.0 *. asin (sqrt a) in 6371000.0 *. c (* Earth radius in meters *) (** Calculate total distance between consecutive points (naive great circle) *) let total_distance t = let rec calculate_distance acc = function | [] | [_] -> acc | p1 :: p2 :: rest -> let lat1, lon1 = Waypoint.to_floats p1 in let lat2, lon2 = Waypoint.to_floats p2 in let distance = great_circle_distance lat1 lon1 lat2 lon2 in calculate_distance (acc +. distance) (p2 :: rest) in calculate_distance 0.0 t.rtepts (** Check if route is empty *) let is_empty t = List.length t.rtepts = 0 (** Get first point *) let first_point t = match t.rtepts with | [] -> None | p :: _ -> Some p (** Get last point *) let last_point t = match List.rev t.rtepts with | [] -> None | p :: _ -> Some p (** {2 Functional Operations} *) (** Update name *) let with_name t name = { t with name = Some name } (** Update comment *) let with_comment t cmt = { t with cmt = Some cmt } (** Update description *) let with_description t desc = { t with desc = Some desc } (** Update source *) let with_source t src = { t with src = Some src } (** Update number *) let with_number t number = { t with number = Some number } (** Update type *) let with_type t type_ = { t with type_ = Some type_ } (** Add point *) let add_point t rtept = { t with rtepts = t.rtepts @ [rtept] } (** Add link *) let add_link t link = { t with links = t.links @ [link] } (** Add extensions *) let add_extensions t extensions = { t with extensions = t.extensions @ extensions } (** Compare routes *) let compare t1 t2 = let name_cmp = Option.compare String.compare t1.name t2.name in if name_cmp <> 0 then name_cmp else let desc_cmp = Option.compare String.compare t1.desc t2.desc in if desc_cmp <> 0 then desc_cmp else List.compare Waypoint.compare t1.rtepts t2.rtepts (** Test route equality *) let equal t1 t2 = compare t1 t2 = 0 (** Pretty print route *) let pp ppf t = match t.name with | Some name -> Format.fprintf ppf "\"%s\" (%d points)" name (point_count t) | None -> Format.fprintf ppf "(unnamed route, %d points)" (point_count t)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>