* CSV export now possible in batch

* Choice for the separator
This commit is contained in:
Pascal Brisset
2009-05-08 20:35:58 +00:00
parent 5d1cbae831
commit 92d68d7cf8
3 changed files with 108 additions and 49 deletions
+30 -6
View File
@@ -4,7 +4,6 @@
<glade-interface>
<widget class="GtkWindow" id="export">
<property name="visible">True</property>
<property name="title" translatable="yes">Save CSV</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
@@ -14,7 +13,7 @@
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
@@ -29,9 +28,9 @@
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
@@ -142,6 +141,31 @@
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Sep:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
@@ -150,7 +174,7 @@
</child>
<child>
<widget class="GtkEventBox" id="box_choose_interpol">
<widget class="GtkEventBox" id="box_choose_sep">
<property name="visible">True</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
@@ -203,7 +227,7 @@
<widget class="GtkButton" id="button_cancel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
+49 -19
View File
@@ -26,7 +26,7 @@
open Printf
open Latlong
let (//) = Filename.concat
let class_name="telemetry"
@@ -85,7 +85,8 @@ type timestamp =
(*****************************************************************************)
let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data timestamp filename ->
let export_values = fun ?(sep="tab") ?(export_geo_pos=true) (model:GTree.tree_store) data timestamp filename ->
let sep = if sep = "tab" then "\t" else sep in
let fields_to_export = ref [] in
model#foreach (fun _path row ->
if model#get ~row ~column:col_to_export then begin
@@ -108,8 +109,8 @@ let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data tim
(* Print the header *)
fprintf f "Time";
if export_geo_pos then
fprintf f ";GPS lat(deg);GPS long(deg)";
List.iter (fun (m,field) -> fprintf f ";%s:%s" m field) !fields_to_export;
fprintf f "%sGPS lat(deg)%sGPS long(deg)" sep sep;
List.iter (fun (m,field) -> fprintf f "%s%s:%s" sep m field) !fields_to_export;
fprintf f "\n%!";
(* Store for the current values *)
@@ -117,25 +118,35 @@ let export_values = fun ?(export_geo_pos=true) (model:GTree.tree_store) data tim
and time = ref (match data with (t, _, _)::_ -> t | _ -> 0.) in
let print_last_values = fun t ->
fprintf f "%.3f" t;
let all_values = ref true in
let lookup = fun m field ->
try Pprz.string_of_value (Hashtbl.find last_values (m,field)) with Not_found -> "" in
try Pprz.string_of_value (Hashtbl.find last_values (m,field)) with Not_found -> all_values := false; "" in
let buf = Buffer.create 64 in
bprintf buf "%.3f" t;
if export_geo_pos then begin
try
let utm_east = float_of_string (lookup "GPS" "utm_east") /. 100.
and utm_north = float_of_string (lookup "GPS" "utm_north") /. 100.
and utm_zone = int_of_string (lookup "GPS" "utm_zone") in
let wgs84 = Latlong.of_utm WGS84 {utm_x=utm_east; utm_y=utm_north; utm_zone=utm_zone} in
fprintf f ";%.6f;%.6f" ((Rad>>Deg) wgs84.posn_lat) ((Rad>>Deg) wgs84.posn_long)
bprintf buf "%s%.6f%s%.6f" sep ((Rad>>Deg) wgs84.posn_lat) sep ((Rad>>Deg) wgs84.posn_long)
with
exc -> fprintf stderr "%s\n%!" (Printexc.to_string exc)
Failure "float_of_string" -> ()
| exc -> fprintf stderr "%s\n%!" (Printexc.to_string exc)
end;
List.iter
(fun (m,field) ->
let v = lookup m field in
fprintf f ";%s" v)
bprintf buf "%s%s" sep v)
!fields_to_export;
fprintf f "\n%!" in
if !all_values then
fprintf f "%s\n" (Buffer.contents buf) in
(* Write one line per time stamp. *)
List.iter (fun (t, msg, fields) ->
@@ -185,8 +196,7 @@ let read_preferences = fun () ->
(** The save file dialog box *)
let save_values = fun w log_filename save ->
let filename = Env.paparazzi_home // "var" // "logs" // log_filename ^ ".csv" in
let save_values = fun w filename save ->
match GToolbox.select_file ~title:"Save Values" ~filename () with
None -> ()
| Some file ->
@@ -196,7 +206,7 @@ let save_values = fun w log_filename save ->
(*****************************************************************************)
(** The popup window displaying values to export *)
let popup = fun xml log_filename data ->
let popup = fun ?(no_gui = false) xml log_filename data ->
(* Build the list window *)
let file = Env.paparazzi_src // "sw" // "logalizer" // "export.glade" in
let w = new Gtk_export.export ~file () in
@@ -236,11 +246,15 @@ let popup = fun xml log_filename data ->
(* The combo box for the extrapolation FIXME
let strings = ["Last Value"; "Linear Extrapolation"] in
let (combo, (tree, column)) = GEdit.combo_box_text ~packing:w#box_choose_interpol#add ~strings () in
(* The combo box for the separator *)
let strings = ["tab"; ";"; ","] in
let (combo, (tree, column)) = GEdit.combo_box_text ~packing:w#box_choose_sep#add ~strings () in
tree#foreach (fun _path row -> combo#set_active_iter (Some row); true); (* Select the first *)
*)
let get_separator = fun () ->
match combo#active_iter with
| None -> failwith "get_timestamp"
| Some row ->
combo#model#get ~row ~column in
ignore (w#button_cancel#connect#clicked (fun () -> w#export#destroy ()));
@@ -252,5 +266,21 @@ let popup = fun xml log_filename data ->
Period (float_of_string w#entry_period#text)
else
Msg combo_value in
save_values w log_filename (fun x -> export_values ~export_geo_pos:w#checkbutton_LL#active model data timestamp x) in
ignore (w#button_save#connect#clicked callback)
let sep = get_separator () in
let do_export = fun x -> export_values ~sep ~export_geo_pos:w#checkbutton_LL#active model data timestamp x in
let default_filename = Env.paparazzi_home // "var" // "logs" // log_filename ^ ".csv" in
if no_gui then
do_export default_filename
else
save_values w default_filename do_export in
ignore (w#button_save#connect#clicked callback);
if no_gui then begin
callback ();
w#export#destroy ()
end else
w#export#show ()
+29 -24
View File
@@ -24,14 +24,13 @@
*
*)
module LL = Latlong
open LL
open Latlong
open Printf
let (//) = Filename.concat
let logs_dir = Env.paparazzi_home // "var" // "logs"
let sample_kml = Env.paparazzi_home // "data/maps/sample_path.kml"
let verbose = ref false
class type text_value = object method text : string end
@@ -284,9 +283,9 @@ let write_kml = fun plot log_name values ->
and y = snd ys.(i) /. 100.
and z = truncate (snd zs.(i))
and a = snd alts.(i) /. 100. in
let utm = { LL.utm_x = x; LL.utm_y = y; LL.utm_zone = z } in
let utm = { utm_x = x; utm_y = y; utm_zone = z } in
if z <> 0 then
l := (LL.of_utm LL.WGS84 utm, a) :: !l
l := (of_utm WGS84 utm, a) :: !l
done;
let l = List.rev !l in
let xml = Xml.parse_file sample_kml in
@@ -326,7 +325,7 @@ let write_kml = fun plot log_name values ->
let add_ac_submenu = fun protocol ?(factor=object method text="1" end) plot menubar (curves_menu_fact: GMenu.menu GMenu.factory) ac menu_name l raw_msgs ->
let add_ac_submenu = fun ?(export=false) protocol ?(factor=object method text="1" end) plot menubar (curves_menu_fact: GMenu.menu GMenu.factory) ac menu_name l raw_msgs ->
let menu = GMenu.menu () in
let menuitem = GMenu.menu_item ~label:menu_name () in
menuitem#set_submenu menu;
@@ -370,13 +369,14 @@ let add_ac_submenu = fun protocol ?(factor=object method text="1" end) plot menu
snd (List.find (fun (m, _) -> m.Pprz.name = "GPS") l) in
write_kml plot menu_name gps_values in
ignore (menu_fact#add_item ~callback "Export KML path");
let callback = fun () ->
Export.popup protocol menu_name raw_msgs in
ignore (menu_fact#add_item ~callback "Export CSV")
let callback = fun ?no_gui () ->
Export.popup ?no_gui protocol menu_name raw_msgs in
ignore (menu_fact#add_item ~callback "Export CSV");
if export then
callback ~no_gui:true ()
let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) curves_fact xml_file ->
let load_log = fun ?export ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory) curves_fact xml_file ->
Debug.call 'p' (fun f -> fprintf f "load_log: %s\n" xml_file);
let xml = Xml.parse_file xml_file in
let data_file = ExtXml.attrib xml "data_file" in
@@ -436,7 +436,9 @@ let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory)
raw_msgs := (t, msg_name, vs) :: !raw_msgs
)
with
exc -> prerr_endline (Printexc.to_string exc)
exc ->
if !verbose then
prerr_endline (Printexc.to_string exc)
done
with
End_of_file ->
@@ -475,7 +477,7 @@ let load_log = fun ?factor (plot:plot) (menubar:GMenu.menu_shell GMenu.factory)
(* Store data for other windows *)
logs_menus := (ac, menu_name, (msgs, raw_msgs), protocol) :: !logs_menus;
add_ac_submenu protocol ?factor plot menubar curves_fact ac menu_name msgs raw_msgs;
add_ac_submenu ?export protocol ?factor plot menubar curves_fact ac menu_name msgs raw_msgs;
)
acs
@@ -518,7 +520,7 @@ let screenshot = fun frame ->
(*****************************************************************************)
let rec plot_window = fun init ->
let rec plot_window = fun ?export init ->
let plotter = GWindow.window ~allow_shrink:true ~title:"Log Plotter" () in
plotter#set_icon (Some (GdkPixbuf.from_file Env.icon_file));
let vbox = GPack.vbox ~packing:plotter#add () in
@@ -606,24 +608,27 @@ let rec plot_window = fun init ->
ignore(open_log_item#connect#activate ~callback:(fun () -> let factor = (factor:>text_value) in open_log ~factor plot factory curves_menu_fact ()));
List.iter (fun f -> load_log ~factor:(factor:>text_value) plot factory curves_menu_fact f) init;
List.iter (fun f -> load_log ?export ~factor:(factor:>text_value) plot factory curves_menu_fact f) init;
plotter#add_accel_group accel_group;
plotter#show ()
let _ =
let logs = ref [] in
(***************************** Main ****************************************)
let () =
let logs = ref []
and export = ref false in
Arg.parse
[]
[ ("-export_csv", Arg.Set export, "Export in CSV in batch mode according to saved preferences (conf/%gconf.xml)");
("-v", Arg.Set verbose, "Verbose")]
(fun x -> logs := x :: !logs)
"Usage: plot <log files>";
plot_window !logs;
plot_window ~export: !export !logs;
let loop = Glib.Main.create true in
while Glib.Main.is_running loop do
ignore (Glib.Main.iteration true)
done
if not !export then
let loop = Glib.Main.create true in
while Glib.Main.is_running loop do
ignore (Glib.Main.iteration true)
done