diff --git a/lib/gpx/doc.ml b/lib/gpx/doc.ml index a61ad37..6e371e9 100644 --- a/lib/gpx/doc.ml +++ b/lib/gpx/doc.ml @@ -149,6 +149,14 @@ let stats t = { has_time = has_time t; } +(** Pretty print statistics *) +let pp_stats ppf t = + let s = stats t in + Format.fprintf ppf "@[GPX Statistics:@, Waypoints: %d@, Routes: %d@, Tracks: %d@, Total points: %d@, Has elevation data: %s@, Has time data: %s@]" + s.waypoint_count s.route_count s.track_count s.total_points + (if s.has_elevation then "yes" else "no") + (if s.has_time then "yes" else "no") + (** {2 Comparison and Utilities} *) (** Compare documents *) @@ -176,15 +184,3 @@ let pp ppf t = t.version t.creator stats.waypoint_count stats.route_count stats.track_count stats.total_points -(** Print document statistics *) -let print_stats t = - let stats = stats t in - Printf.printf "GPX Statistics:\n"; - Printf.printf " Version: %s\n" t.version; - Printf.printf " Creator: %s\n" t.creator; - Printf.printf " Waypoints: %d\n" stats.waypoint_count; - Printf.printf " Routes: %d\n" stats.route_count; - Printf.printf " Tracks: %d\n" stats.track_count; - Printf.printf " Total points: %d\n" stats.total_points; - Printf.printf " Has elevation data: %s\n" (if stats.has_elevation then "yes" else "no"); - Printf.printf " Has time data: %s\n" (if stats.has_time then "yes" else "no") \ No newline at end of file diff --git a/lib/gpx/doc.mli b/lib/gpx/doc.mli index 1de3721..2cf6916 100644 --- a/lib/gpx/doc.mli +++ b/lib/gpx/doc.mli @@ -113,6 +113,9 @@ val is_empty : t -> bool (** Get document statistics *) val stats : t -> stats +(** Pretty print statistics *) +val pp_stats : Format.formatter -> t -> unit + (** {2 Comparison and Utilities} *) (** Compare documents *) @@ -122,7 +125,4 @@ val compare : t -> t -> int val equal : t -> t -> bool (** Pretty print document *) -val pp : Format.formatter -> t -> unit - -(** Print document statistics to stdout *) -val print_stats : t -> unit \ No newline at end of file +val pp : Format.formatter -> t -> unit \ No newline at end of file diff --git a/lib/gpx_eio/gpx_eio.ml b/lib/gpx_eio/gpx_eio.ml index 3953c34..40de110 100644 --- a/lib/gpx_eio/gpx_eio.ml +++ b/lib/gpx_eio/gpx_eio.ml @@ -28,62 +28,6 @@ let make_waypoint ~fs:_ ~lat ~lon ?name ?desc () = { wpt with name; desc } | (Error e, _) | (_, Error e) -> failwith ("Invalid coordinate: " ^ e) -(** Create simple track from coordinate list *) -let make_track_from_coords ~fs:_ ~name coords = - Gpx.Track.make_from_coords ~name coords - -(** Create simple route from coordinate list *) -let make_route_from_coords ~fs:_ ~name coords = - Gpx.Route.make_from_coords ~name coords - -(** Extract coordinates from waypoints *) -let waypoint_coords wpt = Gpx.Waypoint.to_floats wpt - -(** Extract coordinates from track *) -let track_coords trk = Gpx.Track.to_coords trk - -(** Extract coordinates from route *) -let route_coords rte = Gpx.Route.to_coords rte - -(** Count total points in GPX *) -let count_points gpx = - let waypoints = Gpx.Doc.waypoints gpx in - let routes = Gpx.Doc.routes gpx in - let tracks = Gpx.Doc.tracks gpx in - List.length waypoints + - List.fold_left (fun acc r -> acc + List.length (Gpx.Route.points r)) 0 routes + - List.fold_left (fun acc t -> acc + Gpx.Track.point_count t) 0 tracks - -(** Get GPX statistics *) -type gpx_stats = { - waypoint_count : int; - route_count : int; - track_count : int; - total_points : int; - has_elevation : bool; - has_time : bool; -} - -let stats gpx = - let waypoints = Gpx.Doc.waypoints gpx in - let routes = Gpx.Doc.routes gpx in - let tracks = Gpx.Doc.tracks gpx in - { - waypoint_count = List.length waypoints; - route_count = List.length routes; - track_count = List.length tracks; - total_points = count_points gpx; - has_elevation = List.exists (fun w -> Gpx.Waypoint.elevation w <> None) waypoints; - has_time = List.exists (fun w -> Gpx.Waypoint.time w <> None) waypoints; - } - (** Pretty print GPX statistics *) let print_stats gpx = - let stats = stats gpx in - Printf.printf "GPX Statistics:\\n"; - Printf.printf " Waypoints: %d\\n" stats.waypoint_count; - Printf.printf " Routes: %d\\n" stats.route_count; - Printf.printf " Tracks: %d\\n" stats.track_count; - Printf.printf " Total Points: %d\\n" stats.total_points; - Printf.printf " Has Elevation: %b\\n" stats.has_elevation; - Printf.printf " Has Time: %b\\n" stats.has_time \ No newline at end of file + Format.printf "%a@." Gpx.Doc.pp_stats gpx \ No newline at end of file diff --git a/lib/gpx_eio/gpx_eio.mli b/lib/gpx_eio/gpx_eio.mli index 61fc9cb..e2c4796 100644 --- a/lib/gpx_eio/gpx_eio.mli +++ b/lib/gpx_eio/gpx_eio.mli @@ -93,57 +93,6 @@ val to_sink : ?validate:bool -> [> Eio.Flow.sink_ty ] Eio.Resource.t -> Gpx.t -> @raises Gpx.Gpx_error on invalid coordinates *) val make_waypoint : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> lat:float -> lon:float -> ?name:string -> ?desc:string -> unit -> Gpx.Waypoint.t -(** Create track from coordinate list. - @param fs Filesystem capability (unused, for API consistency) - @param name Track name - @param coords List of (latitude, longitude) pairs - @return Track with single segment - @raises Gpx.Gpx_error on invalid coordinates *) -val make_track_from_coords : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> name:string -> (float * float) list -> Gpx.Track.t - -(** Create route from coordinate list. - @param fs Filesystem capability (unused, for API consistency) - @param name Route name - @param coords List of (latitude, longitude) pairs - @return Route - @raises Gpx.Gpx_error on invalid coordinates *) -val make_route_from_coords : fs:[> Eio.Fs.dir_ty ] Eio.Path.t -> name:string -> (float * float) list -> Gpx.Route.t - -(** Extract coordinates from waypoint. - @param wpt Waypoint data - @return (latitude, longitude) as floats *) -val waypoint_coords : Gpx.Waypoint.t -> float * float - -(** Extract coordinates from track. - @param track Track - @return List of (latitude, longitude) pairs *) -val track_coords : Gpx.Track.t -> (float * float) list - -(** Extract coordinates from route. - @param route Route - @return List of (latitude, longitude) pairs *) -val route_coords : Gpx.Route.t -> (float * float) list - -(** Count total points in GPX document. - @param gpx GPX document - @return Total number of waypoints, route points, and track points *) -val count_points : Gpx.t -> int - -(** GPX statistics record *) -type gpx_stats = { - waypoint_count : int; (** Number of waypoints *) - route_count : int; (** Number of routes *) - track_count : int; (** Number of tracks *) - total_points : int; (** Total geographic points *) - has_elevation : bool; (** Document contains elevation data *) - has_time : bool; (** Document contains time data *) -} - -(** Get GPX document statistics. - @param gpx GPX document - @return Statistics summary *) -val stats : Gpx.t -> gpx_stats - (** Print GPX statistics to stdout. @param gpx GPX document *) val print_stats : Gpx.t -> unit diff --git a/lib/gpx_unix/gpx_unix.ml b/lib/gpx_unix/gpx_unix.ml index b4f5861..0a474fd 100644 --- a/lib/gpx_unix/gpx_unix.ml +++ b/lib/gpx_unix/gpx_unix.ml @@ -1,8 +1,5 @@ (** High-level Unix API for GPX operations *) -(** Result binding operators *) -let (let*) = Result.bind - (* Re-export IO module *) module IO = Gpx_io @@ -41,88 +38,6 @@ let make_waypoint ~lat ~lon ?name ?desc () = Ok wpt | (Error e, _) | (_, Error e) -> Error (Gpx.Error.invalid_coordinate e) -(** Create simple track from coordinate list *) -let make_track_from_coords ~name coords = - let make_trkpt (lat, lon) = - match (Coordinate.latitude lat, Coordinate.longitude lon) with - | (Ok lat, Ok lon) -> Ok (Waypoint.make lat lon) - | (Error e, _) | (_, Error e) -> Error (Gpx.Error.invalid_coordinate e) - in - let rec convert_coords acc = function - | [] -> Ok (List.rev acc) - | coord :: rest -> - match make_trkpt coord with - | Ok trkpt -> convert_coords (trkpt :: acc) rest - | Error e -> Error e - in - let* _trkpts = convert_coords [] coords in - Ok (Track.make_from_coords ~name coords) - -(** Create simple route from coordinate list *) -let make_route_from_coords ~name coords = - let make_rtept (lat, lon) = - match (Coordinate.latitude lat, Coordinate.longitude lon) with - | (Ok lat, Ok lon) -> Ok (Waypoint.make lat lon) - | (Error e, _) | (_, Error e) -> Error (Gpx.Error.invalid_coordinate e) - in - let rec convert_coords acc = function - | [] -> Ok (List.rev acc) - | coord :: rest -> - match make_rtept coord with - | Ok rtept -> convert_coords (rtept :: acc) rest - | Error e -> Error e - in - let* _rtepts = convert_coords [] coords in - Ok (Route.make_from_coords ~name coords) - -(** Extract coordinates from waypoints *) -let waypoint_coords wpt = Waypoint.to_floats wpt - -(** Extract coordinates from track *) -let track_coords track = Track.to_coords track - -(** Extract coordinates from route *) -let route_coords route = Route.to_coords route - -(** Count total points in GPX *) -let count_points gpx = - let waypoints = Doc.waypoints gpx in - let routes = Doc.routes gpx in - let tracks = Doc.tracks gpx in - List.length waypoints + - List.fold_left (fun acc r -> acc + List.length (Route.points r)) 0 routes + - List.fold_left (fun acc t -> acc + Track.point_count t) 0 tracks - -(** Get GPX statistics *) -type gpx_stats = { - waypoint_count : int; - route_count : int; - track_count : int; - total_points : int; - has_elevation : bool; - has_time : bool; -} - -let stats gpx = - let waypoints = Doc.waypoints gpx in - let routes = Doc.routes gpx in - let tracks = Doc.tracks gpx in - { - waypoint_count = List.length waypoints; - route_count = List.length routes; - track_count = List.length tracks; - total_points = count_points gpx; - has_elevation = List.exists (fun w -> Waypoint.elevation w <> None) waypoints; - has_time = List.exists (fun w -> Waypoint.time w <> None) waypoints; - } - (** Pretty print GPX statistics *) let print_stats gpx = - let stats = stats gpx in - Printf.printf "GPX Statistics:\n"; - Printf.printf " Waypoints: %d\n" stats.waypoint_count; - Printf.printf " Routes: %d\n" stats.route_count; - Printf.printf " Tracks: %d\n" stats.track_count; - Printf.printf " Total points: %d\n" stats.total_points; - Printf.printf " Has elevation data: %s\n" (if stats.has_elevation then "yes" else "no"); - Printf.printf " Has time data: %s\n" (if stats.has_time then "yes" else "no") \ No newline at end of file + Format.printf "%a@." Doc.pp_stats gpx \ No newline at end of file diff --git a/lib/gpx_unix/gpx_unix.mli b/lib/gpx_unix/gpx_unix.mli index fac59be..595bfff 100644 --- a/lib/gpx_unix/gpx_unix.mli +++ b/lib/gpx_unix/gpx_unix.mli @@ -32,36 +32,5 @@ val validate : t -> validation_result (** Create simple waypoint *) val make_waypoint : lat:float -> lon:float -> ?name:string -> ?desc:string -> unit -> (Waypoint.t, error) result -(** Create simple track from coordinate list *) -val make_track_from_coords : name:string -> (float * float) list -> (Track.t, error) result - -(** Create simple route from coordinate list *) -val make_route_from_coords : name:string -> (float * float) list -> (Route.t, error) result - -(** Extract coordinates from waypoints *) -val waypoint_coords : Waypoint.t -> float * float - -(** Extract coordinates from track *) -val track_coords : Track.t -> (float * float) list - -(** Extract coordinates from route *) -val route_coords : Route.t -> (float * float) list - -(** Count total points in GPX *) -val count_points : t -> int - -(** GPX statistics *) -type gpx_stats = { - waypoint_count : int; - route_count : int; - track_count : int; - total_points : int; - has_elevation : bool; - has_time : bool; -} - -(** Get GPX statistics *) -val stats : t -> gpx_stats - (** Pretty print GPX statistics *) val print_stats : t -> unit \ No newline at end of file