}
return v * sign;
}
+
+ static String replace_extension(String input, String extension) {
+ int dot = input.lastIndexOf(".");
+ if (dot > 0)
+ input = input.substring(0,dot);
+ return input.concat(extension);
+ }
}
import java.text.*;
import java.util.*;
-import altosui.AltosRecord;
-
-public class AltosCSV {
+public class AltosCSV implements AltosWriter {
File name;
PrintStream out;
boolean header_written;
LinkedList<AltosRecord> pad_records;
AltosState state;
- static final int ALTOS_CSV_VERSION = 1;
+ static final int ALTOS_CSV_VERSION = 2;
- /* Version 1 format:
+ /* Version 2 format:
*
* General info
* version number
void write_general(AltosRecord record) {
out.printf("%s, %d, %d, %s, %8.2f, %4d, %3d",
- record.version, record.serial, record.flight, record.callsign,
+ ALTOS_CSV_VERSION, record.serial, record.flight, record.callsign,
(double) record.time,
record.rssi,
record.status & 0x7f);
JFrame frame;
Thread thread;
AltosRecordIterable iterable;
- AltosCSV writer;
+ AltosWriter writer;
+ JFileChooser csv_chooser;
+ JComboBox combo_box;
+
+ static String[] combo_box_items = { "CSV", "KML" };
+
+ void set_default_file() {
+ File current = csv_chooser.getSelectedFile();
+ String current_name = current.getName();
+ String new_name = null;
+ String selected = (String) combo_box.getSelectedItem();
+
+ if (selected.equals("CSV"))
+ new_name = Altos.replace_extension(current_name, ".csv");
+ else if (selected.equals("KML"))
+ new_name = Altos.replace_extension(current_name, ".kml");
+ if (new_name != null)
+ csv_chooser.setSelectedFile(new File(new_name));
+ }
public void run() {
AltosLogfileChooser chooser;
iterable = chooser.runDialog();
if (iterable == null)
return;
- JFileChooser csv_chooser;
- File file = chooser.file();
- String path = file.getPath();
- int dot = path.lastIndexOf(".");
- if (dot >= 0)
- path = path.substring(0,dot);
- path = path.concat(".csv");
- csv_chooser = new JFileChooser(path);
- csv_chooser.setSelectedFile(new File(path));
+ csv_chooser = new JFileChooser(chooser.file());
+ combo_box = new JComboBox(combo_box_items);
+ combo_box.addActionListener(this);
+ csv_chooser.setAccessory(combo_box);
+ csv_chooser.setSelectedFile(chooser.file());
+ set_default_file();
int ret = csv_chooser.showSaveDialog(frame);
if (ret == JFileChooser.APPROVE_OPTION) {
+ File file = csv_chooser.getSelectedFile();
+ String type = (String) combo_box.getSelectedItem();
try {
- writer = new AltosCSV(csv_chooser.getSelectedFile());
+ if (type.equals("CSV"))
+ writer = new AltosCSV(file);
+ else
+ writer = new AltosKML(file);
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(frame,
file.getName(),
}
public void actionPerformed(ActionEvent e) {
+ System.out.printf("command %s param %s\n", e.getActionCommand(), e.paramString());
+ if (e.getActionCommand().equals("comboBoxChanged"))
+ set_default_file();
}
public AltosCSVUI(JFrame in_frame) {
--- /dev/null
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package altosui;
+
+import java.lang.*;
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+public class AltosKML implements AltosWriter {
+
+ File name;
+ PrintStream out;
+ int state = -1;
+ AltosRecord prev = null;
+
+ static final String[] kml_state_colors = {
+ "FF000000",
+ "FF000000",
+ "FF000000",
+ "FF0000FF",
+ "FF4080FF",
+ "FF00FFFF",
+ "FFFF0000",
+ "FF00FF00",
+ "FF000000",
+ "FFFFFFFF"
+ };
+
+ static final String kml_header_start =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" +
+ "<Document>\n" +
+ " <name>AO Flight#%d S/N: %03d</name>\n" +
+ " <description>\n";
+ static final String kml_header_end =
+ " </description>\n" +
+ " <open>0</open>\n";
+
+ static final String kml_style_start =
+ " <Style id=\"ao-flightstate-%s\">\n" +
+ " <LineStyle><color>%s</color><width>4</width></LineStyle>\n" +
+ " <BalloonStyle>\n" +
+ " <text>\n";
+
+ static final String kml_style_end =
+ " </text>\n" +
+ " </BalloonStyle>\n" +
+ " </Style>\n";
+
+ static final String kml_placemark_start =
+ " <Placemark>\n" +
+ " <name>%s</name>\n" +
+ " <styleUrl>#ao-flightstate-%s</styleUrl>\n" +
+ " <LineString>\n" +
+ " <tessellate>1</tessellate>\n" +
+ " <altitudeMode>absolute</altitudeMode>\n" +
+ " <coordinates>\n";
+
+ static final String kml_coord_fmt =
+ " %12.7f, %12.7f, %12.7f <!-- alt %12.7f time %12.7f sats %d -->\n";
+
+ static final String kml_placemark_end =
+ " </coordinates>\n" +
+ " </LineString>\n" +
+ " </Placemark>\n";
+
+ static final String kml_footer =
+ "</Document>\n" +
+ "</kml>\n";
+
+ void start (AltosRecord record) {
+ out.printf(kml_header_start, record.flight, record.serial);
+ out.printf("Date: %04d-%02d-%02d\n",
+ record.gps.year, record.gps.month, record.gps.day);
+ out.printf("Time: %2d:%02d:%02d\n",
+ record.gps.hour, record.gps.minute, record.gps.second);
+ out.printf("%s", kml_header_end);
+ }
+
+ boolean started = false;
+
+ void state_start(AltosRecord record) {
+ String state_name = Altos.state_name(record.state);
+ out.printf(kml_style_start, state_name, kml_state_colors[record.state]);
+ out.printf("\tState: %s\n", state_name);
+ out.printf("%s", kml_style_end);
+ out.printf(kml_placemark_start, state_name, state_name);
+ }
+
+ void state_end(AltosRecord record) {
+ out.printf("%s", kml_placemark_end);
+ }
+
+ void coord(AltosRecord record) {
+ AltosGPS gps = record.gps;
+ out.printf(kml_coord_fmt,
+ gps.lon, gps.lat,
+ record.filtered_altitude(), (double) gps.alt,
+ record.time, gps.nsat);
+ }
+
+ void end() {
+ out.printf("%s", kml_footer);
+ }
+
+ public void close() {
+ if (prev != null) {
+ state_end(prev);
+ end();
+ prev = null;
+ }
+ }
+
+ public void write(AltosRecord record) {
+ AltosGPS gps = record.gps;
+
+ if (gps == null)
+ return;
+ if (!started) {
+ start(record);
+ started = true;
+ }
+ if (prev != null &&
+ prev.gps.second == record.gps.second &&
+ prev.gps.minute == record.gps.minute &&
+ prev.gps.hour == record.gps.hour)
+ return;
+ if (record.state != state) {
+ state = record.state;
+ if (prev != null) {
+ coord(record);
+ state_end(prev);
+ }
+ state_start(record);
+ }
+ coord(record);
+ prev = record;
+ }
+
+ public void write(AltosRecordIterable iterable) {
+ for (AltosRecord record : iterable)
+ write(record);
+ }
+
+ public AltosKML(File in_name) throws FileNotFoundException {
+ name = in_name;
+ out = new PrintStream(name);
+ }
+
+ public AltosKML(String in_string) throws FileNotFoundException {
+ this(new File(in_string));
+ }
+}
}
- static String replace_extension(String input, String extension) {
- int dot = input.lastIndexOf(".");
- if (dot > 0)
- input = input.substring(0,dot);
- return input.concat(extension);
- }
-
static AltosRecordIterable open_logfile(String filename) {
File file = new File (filename);
try {
}
}
- static AltosCSV open_csv(String filename) {
+ static AltosWriter open_csv(String filename) {
File file = new File (filename);
try {
return new AltosCSV(file);
}
}
- static void process_file(String input) {
- String output = replace_extension(input,".csv");
- if (input.equals(output)) {
- System.out.printf("Not processing '%s'\n", input);
- return;
+ static AltosWriter open_kml(String filename) {
+ File file = new File (filename);
+ try {
+ return new AltosKML(file);
+ } catch (FileNotFoundException fe) {
+ System.out.printf("Cannot open '%s'\n", filename);
+ return null;
}
- System.out.printf("Processing \"%s\" to \"%s\"\n", input, output);
+ }
+
+ static final int process_csv = 1;
+ static final int process_kml = 2;
+
+ static void process_file(String input, int process) {
AltosRecordIterable iterable = open_logfile(input);
if (iterable == null)
return;
- AltosCSV writer = open_csv(output);
- if (writer == null)
- return;
- writer.write(iterable);
- writer.close();
+ if (process == 0)
+ process = process_csv;
+ if ((process & process_csv) != 0) {
+ String output = Altos.replace_extension(input,".csv");
+ System.out.printf("Processing \"%s\" to \"%s\"\n", input, output);
+ if (input.equals(output)) {
+ System.out.printf("Not processing '%s'\n", input);
+ } else {
+ AltosWriter writer = open_csv(output);
+ if (writer != null) {
+ writer.write(iterable);
+ writer.close();
+ }
+ }
+ }
+ if ((process & process_kml) != 0) {
+ String output = Altos.replace_extension(input,".kml");
+ System.out.printf("Processing \"%s\" to \"%s\"\n", input, output);
+ if (input.equals(output)) {
+ System.out.printf("Not processing '%s'\n", input);
+ } else {
+ AltosWriter writer = open_kml(output);
+ if (writer == null)
+ return;
+ writer.write(iterable);
+ writer.close();
+ }
+ }
}
public static void main(final String[] args) {
-
+ int process = 0;
/* Handle batch-mode */
if (args.length > 0) {
- for (int i = 0; i < args.length; i++)
- process_file(args[i]);
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("--kml"))
+ process |= process_kml;
+ else if (args[i].equals("--csv"))
+ process |= process_csv;
+ else
+ process_file(args[i], process);
+ }
} else {
AltosUI altosui = new AltosUI();
altosui.setVisible(true);
--- /dev/null
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package altosui;
+
+import java.lang.*;
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+public interface AltosWriter {
+
+ public void write(AltosRecord record);
+
+ public void write(AltosRecordIterable iterable);
+
+ public void close();
+}
AltosHexfile.java \
Altos.java \
AltosInfoTable.java \
+ AltosKML.java \
AltosLine.java \
AltosLogfileChooser.java \
AltosLog.java \
AltosTelemetry.java \
AltosTelemetryIterable.java \
AltosUI.java \
- AltosDataPointReader.java \
- AltosCsvReader.java \
- AltosDataPoint.java \
- AltosGraph.java \
- AltosGraphTime.java \
- AltosGraphUI.java \
- AltosGraphDataChooser.java \
+ AltosWriter.java \
+ AltosDataPointReader.java \
+ AltosCsvReader.java \
+ AltosDataPoint.java \
+ AltosGraph.java \
+ AltosGraphTime.java \
+ AltosGraphUI.java \
+ AltosGraphDataChooser.java \
AltosVoice.java
JFREECHART_CLASS= \
WINDOWS_FILES=$(FAT_FILES) altos.dll $(top_srcdir)/telemetrum.inf $(WINDOWS_ICON)
-all-local: classes/altosui $(JAR) altosui altosui-test
+all-local: classes/altosui $(JAR) altosui altosui-test altosui-jdb
clean-local:
-rm -rf classes $(JAR) $(FATJAR) \
$(LINUX_DIST) $(MACOSX_DIST) windows $(WINDOWS_DIST) $(FREETTS_CLASS) \
$(JFREECHART_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt altos-windows.log \
- altosui altosui-test macosx linux
+ altosui altosui-test altosui-jdb macosx linux
if FATINSTALL
echo 'exec java -cp "$(FREETTS)/*" -Djava.library.path="../libaltos/.libs" -jar altosui.jar "$$@"' >> $@
chmod +x $@
+altosui-jdb: Makefile
+ echo "#!/bin/sh" > $@
+ echo 'exec jdb -classpath "classes:../libaltos:$(FREETTS)/*" -Djava.library.path="../libaltos/.libs" altosui/AltosUI "$$@"' >> $@
+ chmod +x $@
+
libaltos.so:
-rm -f "$@"
$(LN_S) ../libaltos/.libs/"$@" .