summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-05-28 21:56:52 -0700
committerKeith Packard <keithp@keithp.com>2014-05-28 22:02:32 -0700
commit3871b9ac036e3adfa1da089245fc7973b268c921 (patch)
treef84cee06faaf7574e81836292b67ac702b69cc1b
parent4cec35564324f909dcddeb7c0d83a2daa8223042 (diff)
telegps: Add 'Info' tab
This contains a summary of the tracking info, including position, speed and course. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altoslib/AltosConvert.java26
-rw-r--r--altoslib/AltosGreatCircle.java26
-rw-r--r--altoslib/AltosState.java24
-rw-r--r--altosui/Makefile.am15
-rw-r--r--altosuilib/AltosCSVUI.java (renamed from altosui/AltosCSVUI.java)7
-rw-r--r--altosuilib/AltosDataChooser.java (renamed from altosui/AltosDataChooser.java)3
-rw-r--r--altosuilib/AltosLed.java (renamed from altosui/AltosLed.java)4
-rw-r--r--altosuilib/AltosLights.java (renamed from altosui/AltosLights.java)4
-rw-r--r--altosuilib/Makefile.am20
-rw-r--r--icon/telegps-128.pngbin0 -> 8736 bytes
-rw-r--r--icon/telegps-16.pngbin0 -> 507 bytes
-rw-r--r--icon/telegps-256.pngbin0 -> 21589 bytes
-rw-r--r--icon/telegps-32.pngbin0 -> 1475 bytes
-rw-r--r--icon/telegps-48.pngbin0 -> 2507 bytes
-rw-r--r--icon/telegps-512.pngbin0 -> 56581 bytes
-rw-r--r--icon/telegps-64.pngbin0 -> 3678 bytes
-rw-r--r--icon/telegps.icobin0 -> 285478 bytes
-rw-r--r--icon/telegps.svg215
-rw-r--r--telegps/Makefile.am1
-rw-r--r--telegps/TeleGPS.java13
-rw-r--r--telegps/TeleGPSInfo.java511
21 files changed, 822 insertions, 47 deletions
diff --git a/altoslib/AltosConvert.java b/altoslib/AltosConvert.java
index 484f6213..a65669da 100644
--- a/altoslib/AltosConvert.java
+++ b/altoslib/AltosConvert.java
@@ -371,4 +371,30 @@ public class AltosConvert {
return 94;
return (int) Math.floor (1.0/2.0 * (24.0e6/32.0) / freq + 0.5);
}
+
+ public static final int BEARING_LONG = 0;
+ public static final int BEARING_SHORT = 1;
+ public static final int BEARING_VOICE = 2;
+
+ public static String bearing_to_words(int length, double bearing) {
+ String [][] bearing_string = {
+ {
+ "North", "North North East", "North East", "East North East",
+ "East", "East South East", "South East", "South South East",
+ "South", "South South West", "South West", "West South West",
+ "West", "West North West", "North West", "North North West"
+ }, {
+ "N", "NNE", "NE", "ENE",
+ "E", "ESE", "SE", "SSE",
+ "S", "SSW", "SW", "WSW",
+ "W", "WNW", "NW", "NNW"
+ }, {
+ "north", "nor nor east", "north east", "east nor east",
+ "east", "east sow east", "south east", "sow sow east",
+ "south", "sow sow west", "south west", "west sow west",
+ "west", "west nor west", "north west", "nor nor west "
+ }
+ };
+ return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16];
+ }
}
diff --git a/altoslib/AltosGreatCircle.java b/altoslib/AltosGreatCircle.java
index 39df4fc8..4782c34d 100644
--- a/altoslib/AltosGreatCircle.java
+++ b/altoslib/AltosGreatCircle.java
@@ -30,30 +30,12 @@ public class AltosGreatCircle implements Cloneable {
static final double rad = Math.PI / 180;
static final double earth_radius = 6371.2 * 1000; /* in meters */
- public static final int BEARING_LONG = 0;
- public static final int BEARING_SHORT = 1;
- public static final int BEARING_VOICE = 2;
+ public static final int BEARING_LONG = AltosConvert.BEARING_LONG;
+ public static final int BEARING_SHORT = AltosConvert.BEARING_SHORT;
+ public static final int BEARING_VOICE = AltosConvert.BEARING_VOICE;
public String bearing_words(int length) {
- String [][] bearing_string = {
- {
- "North", "North North East", "North East", "East North East",
- "East", "East South East", "South East", "South South East",
- "South", "South South West", "South West", "West South West",
- "West", "West North West", "North West", "North North West"
- }, {
- "N", "NNE", "NE", "ENE",
- "E", "ESE", "SE", "SSE",
- "S", "SSW", "SW", "WSW",
- "W", "WNW", "NW", "NNW"
- }, {
- "north", "nor nor east", "north east", "east nor east",
- "east", "east sow east", "south east", "sow sow east",
- "south", "sow sow west", "south west", "west sow west",
- "west", "west nor west", "north west", "nor nor west "
- }
- };
- return bearing_string[length][(int)((bearing / 90 * 8 + 1) / 2)%16];
+ return AltosConvert.bearing_to_words(length, bearing);
}
public AltosGreatCircle (double start_lat, double start_lon, double start_alt,
diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java
index 9e8e22ac..1162e522 100644
--- a/altoslib/AltosState.java
+++ b/altoslib/AltosState.java
@@ -389,6 +389,10 @@ public class AltosState implements Cloneable {
private AltosGpsAltitude gps_altitude;
+ private AltosValue gps_ground_speed;
+ private AltosValue gps_ascent_rate;
+ private AltosValue gps_course;
+
public double altitude() {
double a = altitude.value();
if (a != AltosLib.MISSING)
@@ -419,6 +423,18 @@ public class AltosState implements Cloneable {
gps_altitude.set(new_gps_altitude, time);
}
+ public double gps_ground_speed() {
+ return gps_ground_speed.value();
+ }
+
+ public double gps_ascent_rate() {
+ return gps_ascent_rate.value();
+ }
+
+ public double gps_course() {
+ return gps_course.value();
+ }
+
class AltosPressure extends AltosValue {
void set(double p, double time) {
super.set(p, time);
@@ -695,6 +711,8 @@ public class AltosState implements Cloneable {
gps_altitude = new AltosGpsAltitude();
gps_ground_altitude = new AltosGpsGroundAltitude();
+ gps_ground_speed = new AltosValue();
+ gps_ascent_rate = new AltosValue();
speak_tick = AltosLib.MISSING;
speak_altitude = AltosLib.MISSING;
@@ -877,6 +895,12 @@ public class AltosState implements Cloneable {
gps_ground_altitude.set(gps.alt, time);
}
gps_altitude.set(gps.alt, time);
+ if (gps.climb_rate != AltosLib.MISSING)
+ gps_ascent_rate.set(gps.climb_rate, time);
+ if (gps.ground_speed != AltosLib.MISSING)
+ gps_ground_speed.set(gps.ground_speed, time);
+ if (gps.course != AltosLib.MISSING)
+ gps_course.set(gps.course, time);
}
if (gps.lat != 0 && gps.lon != 0 &&
pad_lat != AltosLib.MISSING &&
diff --git a/altosui/Makefile.am b/altosui/Makefile.am
index c834646d..9eff1614 100644
--- a/altosui/Makefile.am
+++ b/altosui/Makefile.am
@@ -20,7 +20,6 @@ altosui_JAVA = \
AltosConfigureUI.java \
AltosConfigTD.java \
AltosConfigTDUI.java \
- AltosCSVUI.java \
AltosDescent.java \
AltosFlashUI.java \
AltosFlightInfoTableModel.java \
@@ -36,8 +35,6 @@ altosui_JAVA = \
AltosLaunchUI.java \
AltosInfoTable.java \
AltosLanded.java \
- AltosLed.java \
- AltosLights.java \
AltosPad.java \
AltosUIPreferencesBackend.java \
AltosRomconfigUI.java \
@@ -45,8 +42,7 @@ altosui_JAVA = \
AltosGraph.java \
AltosGraphDataPoint.java \
AltosGraphDataSet.java \
- AltosGraphUI.java \
- AltosDataChooser.java
+ AltosGraphUI.java
JFREECHART_CLASS= \
jfreechart.jar
@@ -94,20 +90,13 @@ JAVA_ICONS=\
$(ICONDIR)/altus-metrum-128.png \
$(ICONDIR)/altus-metrum-256.png
-ICONS= $(ICONDIR)/redled.png $(ICONDIR)/redoff.png \
- $(ICONDIR)/greenled.png $(ICONDIR)/greenoff.png \
- $(ICONDIR)/grayled.png $(ICONDIR)/grayoff.png
-
# icon base names for jar
ICONJAR= -C $(ICONDIR) altus-metrum-16.png \
-C $(ICONDIR) altus-metrum-32.png \
-C $(ICONDIR) altus-metrum-48.png \
-C $(ICONDIR) altus-metrum-64.png \
-C $(ICONDIR) altus-metrum-128.png \
- -C $(ICONDIR) altus-metrum-256.png \
- -C $(ICONDIR) redled.png -C $(ICONDIR) redoff.png \
- -C $(ICONDIR) greenled.png -C $(ICONDIR) greenoff.png \
- -C $(ICONDIR) grayon.png -C $(ICONDIR) grayled.png
+ -C $(ICONDIR) altus-metrum-256.png
WINDOWS_ICON=$(ICONDIR)/altus-metrum.ico
diff --git a/altosui/AltosCSVUI.java b/altosuilib/AltosCSVUI.java
index a0fceee5..0a5e4fa2 100644
--- a/altosui/AltosCSVUI.java
+++ b/altosuilib/AltosCSVUI.java
@@ -15,14 +15,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import org.altusmetrum.altoslib_4.*;
-import org.altusmetrum.altosuilib_2.*;
public class AltosCSVUI
extends AltosUIDialog
@@ -43,9 +42,9 @@ public class AltosCSVUI
String selected = (String) combo_box.getSelectedItem();
if (selected.contains("CSV"))
- new_name = Altos.replace_extension(current_name, ".csv");
+ new_name = AltosLib.replace_extension(current_name, ".csv");
else if (selected.contains("KML"))
- new_name = Altos.replace_extension(current_name, ".kml");
+ new_name = AltosLib.replace_extension(current_name, ".kml");
if (new_name != null)
csv_chooser.setSelectedFile(new File(new_name));
}
diff --git a/altosui/AltosDataChooser.java b/altosuilib/AltosDataChooser.java
index 43726a44..14d28115 100644
--- a/altosui/AltosDataChooser.java
+++ b/altosuilib/AltosDataChooser.java
@@ -15,13 +15,12 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
import org.altusmetrum.altoslib_4.*;
-import org.altusmetrum.altosuilib_2.*;
public class AltosDataChooser extends JFileChooser {
JFrame frame;
diff --git a/altosui/AltosLed.java b/altosuilib/AltosLed.java
index 93064f1e..2debb62a 100644
--- a/altosui/AltosLed.java
+++ b/altosuilib/AltosLed.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import javax.swing.*;
@@ -23,7 +23,7 @@ public class AltosLed extends JLabel {
ImageIcon on, off;
ImageIcon create_icon(String path) {
- java.net.URL imgURL = AltosUI.class.getResource(path);
+ java.net.URL imgURL = AltosUILib.class.getResource(path);
if (imgURL != null)
return new ImageIcon(imgURL);
System.err.printf("Cannot find icon \"%s\"\n", path);
diff --git a/altosui/AltosLights.java b/altosuilib/AltosLights.java
index 7ad22f3e..c91b70e9 100644
--- a/altosui/AltosLights.java
+++ b/altosuilib/AltosLights.java
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import java.awt.*;
import javax.swing.*;
@@ -27,7 +27,7 @@ public class AltosLights extends JComponent {
AltosLed red, green;
ImageIcon create_icon(String path, String description) {
- java.net.URL imgURL = AltosUI.class.getResource(path);
+ java.net.URL imgURL = AltosUILib.class.getResource(path);
if (imgURL != null)
return new ImageIcon(imgURL, description);
System.err.printf("Cannot find icon \"%s\"\n", path);
diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am
index 4dc4c47f..f554fd74 100644
--- a/altosuilib/Makefile.am
+++ b/altosuilib/Makefile.am
@@ -50,6 +50,10 @@ altosuilib_JAVA = \
AltosEepromManage.java \
AltosEepromMonitorUI.java \
AltosEepromSelect.java \
+ AltosCSVUI.java \
+ AltosDataChooser.java \
+ AltosLights.java \
+ AltosLed.java \
AltosBTDevice.java \
AltosBTDeviceIterator.java \
AltosBTManage.java \
@@ -58,6 +62,18 @@ altosuilib_JAVA = \
JAR=altosuilib_$(ALTOSUILIB_VERSION).jar
+# Icons
+ICONDIR=$(top_srcdir)/icon
+
+ICONS= $(ICONDIR)/redled.png $(ICONDIR)/redoff.png \
+ $(ICONDIR)/greenled.png $(ICONDIR)/greenoff.png \
+ $(ICONDIR)/grayon.png $(ICONDIR)/grayled.png
+
+# icon base names for jar
+ICONJAR= -C $(ICONDIR) redled.png -C $(ICONDIR) redoff.png \
+ -C $(ICONDIR) greenled.png -C $(ICONDIR) greenoff.png \
+ -C $(ICONDIR) grayon.png -C $(ICONDIR) grayled.png
+
all-local: $(JAR)
clean-local:
@@ -72,5 +88,5 @@ install-altosuilibJAVA: $(JAR)
$(JAVAROOT):
mkdir -p $(JAVAROOT)
-$(JAR): classaltosuilib.stamp
- jar cf $@ -C $(JAVAROOT) .
+$(JAR): classaltosuilib.stamp $(ICONS)
+ jar cf $@ $(ICONJAR) -C $(JAVAROOT) .
diff --git a/icon/telegps-128.png b/icon/telegps-128.png
new file mode 100644
index 00000000..f1343d9e
--- /dev/null
+++ b/icon/telegps-128.png
Binary files differ
diff --git a/icon/telegps-16.png b/icon/telegps-16.png
new file mode 100644
index 00000000..5bd45999
--- /dev/null
+++ b/icon/telegps-16.png
Binary files differ
diff --git a/icon/telegps-256.png b/icon/telegps-256.png
new file mode 100644
index 00000000..46e1670a
--- /dev/null
+++ b/icon/telegps-256.png
Binary files differ
diff --git a/icon/telegps-32.png b/icon/telegps-32.png
new file mode 100644
index 00000000..c8588899
--- /dev/null
+++ b/icon/telegps-32.png
Binary files differ
diff --git a/icon/telegps-48.png b/icon/telegps-48.png
new file mode 100644
index 00000000..3bee98e6
--- /dev/null
+++ b/icon/telegps-48.png
Binary files differ
diff --git a/icon/telegps-512.png b/icon/telegps-512.png
new file mode 100644
index 00000000..47c47003
--- /dev/null
+++ b/icon/telegps-512.png
Binary files differ
diff --git a/icon/telegps-64.png b/icon/telegps-64.png
new file mode 100644
index 00000000..0ee086a6
--- /dev/null
+++ b/icon/telegps-64.png
Binary files differ
diff --git a/icon/telegps.ico b/icon/telegps.ico
new file mode 100644
index 00000000..bedf04ef
--- /dev/null
+++ b/icon/telegps.ico
Binary files differ
diff --git a/icon/telegps.svg b/icon/telegps.svg
new file mode 100644
index 00000000..256b8c5a
--- /dev/null
+++ b/icon/telegps.svg
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ width="191.28"
+ height="245.28"
+ version="1.0"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="altusmetrum-only.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/keithp/src/cc1111/altus-logo/bottom.png"
+ inkscape:export-xdpi="119.89881"
+ inkscape:export-ydpi="119.89881">
+ <metadata
+ id="metadata14">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs12">
+ <linearGradient
+ id="linearGradient3165">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3167" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3169" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3177">
+ <stop
+ style="stop-color:#da7000;stop-opacity:1;"
+ offset="0"
+ id="stop3179" />
+ <stop
+ id="stop3447"
+ offset="0.24528302"
+ style="stop-color:#a63852;stop-opacity:1;" />
+ <stop
+ style="stop-color:#7200a4;stop-opacity:1;"
+ offset="1"
+ id="stop3181" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3169">
+ <stop
+ style="stop-color:#ff8a00;stop-opacity:1;"
+ offset="0"
+ id="stop3171" />
+ <stop
+ id="stop3445"
+ offset="0.71698111"
+ style="stop-color:#c24573;stop-opacity:0.98039216;" />
+ <stop
+ style="stop-color:#8500e7;stop-opacity:0.96078432;"
+ offset="1"
+ id="stop3173" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 121 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="191 : 121 : 1"
+ inkscape:persp3d-origin="95.5 : 80.666667 : 1"
+ id="perspective16" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3169"
+ id="radialGradient3175"
+ cx="951.68713"
+ cy="2305.2668"
+ fx="951.68713"
+ fy="2305.2668"
+ r="951.68701"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="radialGradient3171"
+ cx="951.68713"
+ cy="1205.2668"
+ fx="951.68713"
+ fy="1205.2668"
+ r="951.68701"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3169"
+ id="radialGradient3020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="2305.2668"
+ fx="951.68713"
+ fy="2305.2668"
+ r="951.68701" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="radialGradient3022"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="1205.2668"
+ fx="951.68713"
+ fy="1205.2668"
+ r="951.68701" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3169"
+ id="radialGradient3024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="2305.2668"
+ fx="951.68713"
+ fy="2305.2668"
+ r="951.68701" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="radialGradient3026"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="1205.2668"
+ fx="951.68713"
+ fy="1205.2668"
+ r="951.68701" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3169"
+ id="radialGradient3028"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="2305.2668"
+ fx="951.68713"
+ fy="2305.2668"
+ r="951.68701" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3165"
+ id="radialGradient3030"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2664529,0,-321.14689)"
+ cx="951.68713"
+ cy="1205.2668"
+ fx="951.68713"
+ fy="1205.2668"
+ r="951.68701" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:cy="107.44765"
+ inkscape:cx="270.26251"
+ inkscape:zoom="0.86831672"
+ inkscape:window-height="709"
+ inkscape:window-width="1006"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:window-x="266"
+ inkscape:window-y="43"
+ inkscape:current-layer="svg2"
+ inkscape:window-maximized="0" />
+ <g
+ transform="matrix(0.1,0,0,0.1,1.1516425,2.6405446)"
+ id="g3"
+ style="fill:url(#radialGradient3175);fill-opacity:1;stroke:url(#radialGradient3171);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">
+ <g
+ transform="translate(20.61545,-27.69425)"
+ style="fill:url(#radialGradient3028);fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient3030);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
+ id="g5">
+ <path
+ d="m 931.07168,1164.597 248.86992,-331.80265 416.1687,1338.32935 286.6484,267.1042 -520.4224,0 -270.2797,-262.2181 0,-1033.0627 -160.98492,106.6818 -160.98492,-106.6818 0,1033.0627 -270.2797,262.2181 -520.4224,0 286.6484,-267.1042 416.1687,-1338.32935 248.86992,331.80265 z"
+ id="path7"
+ style="fill:url(#radialGradient3020);fill-opacity:1;stroke:url(#radialGradient3022);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 931.07168,27.69425 224.03682,720.46517 -63.341,76.00913 L 931.07168,486.3269 770.37586,824.16855 707.03486,748.15942 931.07168,27.69425 z"
+ id="path9"
+ style="fill:url(#radialGradient3024);fill-opacity:1;stroke:url(#radialGradient3026);stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/telegps/Makefile.am b/telegps/Makefile.am
index 280b1e40..f8e2e63c 100644
--- a/telegps/Makefile.am
+++ b/telegps/Makefile.am
@@ -15,6 +15,7 @@ telegps_JAVA= \
TeleGPS.java \
TeleGPSStatus.java \
TeleGPSStatusUpdate.java \
+ TeleGPSInfo.java \
TeleGPSConfig.java \
TeleGPSConfigUI.java \
TeleGPSPreferences.java
diff --git a/telegps/TeleGPS.java b/telegps/TeleGPS.java
index ad46fbdd..1bb505e0 100644
--- a/telegps/TeleGPS.java
+++ b/telegps/TeleGPS.java
@@ -53,6 +53,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo
JTabbedPane pane;
AltosSiteMap sitemap;
+ TeleGPSInfo gps_info;
boolean has_map;
JMenuBar menu_bar;
@@ -115,10 +116,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo
public void reset() {
sitemap.reset();
+ gps_info.reset();
}
public void set_font() {
sitemap.set_font();
+ gps_info.set_font();
}
public void font_size_changed(int font_size) {
@@ -135,6 +138,7 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo
state = new AltosState();
sitemap.show(state, listener_state);
+ gps_info.show(state, listener_state);
telegps_status.show(state, listener_state);
}
@@ -225,6 +229,12 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo
}
void export() {
+ AltosDataChooser chooser;
+ chooser = new AltosDataChooser(this);
+ AltosStateIterable states = chooser.runDialog();
+ if (states == null)
+ return;
+ new AltosCSVUI(this, states, chooser.file());
}
void graph() {
@@ -394,6 +404,9 @@ public class TeleGPS extends AltosUIFrame implements AltosFlightDisplay, AltosFo
sitemap = new AltosSiteMap();
pane.add("Site Map", sitemap);
+ gps_info = new TeleGPSInfo();
+ pane.add("Info", gps_info);
+
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
AltosUIPreferences.register_font_listener(this);
diff --git a/telegps/TeleGPSInfo.java b/telegps/TeleGPSInfo.java
new file mode 100644
index 00000000..0fba77d5
--- /dev/null
+++ b/telegps/TeleGPSInfo.java
@@ -0,0 +1,511 @@
+/*
+ * 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 org.altusmetrum.telegps;
+
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_4.*;
+import org.altusmetrum.altosuilib_2.*;
+
+public class TeleGPSInfo extends JComponent implements AltosFlightDisplay {
+ GridBagLayout layout;
+ JLabel cur, max;
+
+ public class Info {
+ JLabel label;
+ JTextField value;
+ AltosLights lights;
+
+ void show() {
+ value.setVisible(true);
+ lights.setVisible(true);
+ label.setVisible(true);
+ }
+
+ void hide() {
+ value.setVisible(false);
+ lights.setVisible(false);
+ label.setVisible(false);
+ }
+
+ void show(AltosState state, AltosListenerState listener_state) {}
+
+ void show(String s) {
+ show();
+ value.setText(s);
+ }
+
+ void show(AltosUnits units, double v) {
+ show(units.show(8, v));
+ }
+
+ void show(String format, double v) {
+ show(String.format(format, v));
+ }
+
+ void reset() {
+ lights.set(false);
+ value.setText("");
+ }
+
+ void set_font() {
+ label.setFont(AltosUILib.label_font);
+ value.setFont(AltosUILib.value_font);
+ }
+
+ public Info (GridBagLayout layout, int y, String text) {
+ GridBagConstraints c = new GridBagConstraints();
+ c.weighty = 1;
+
+ lights = new AltosLights();
+ c.gridx = 0; c.gridy = y;
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.VERTICAL;
+ c.weightx = 0;
+ layout.setConstraints(lights, c);
+ add(lights);
+
+ label = new JLabel(text);
+ label.setFont(AltosUILib.label_font);
+ label.setHorizontalAlignment(SwingConstants.LEFT);
+ c.gridx = 1; c.gridy = y;
+ c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.VERTICAL;
+ c.weightx = 0;
+ layout.setConstraints(label, c);
+ add(label);
+
+ value = new JTextField(AltosUILib.text_width);
+ value.setFont(AltosUILib.value_font);
+ value.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = 2; c.gridy = y;
+ c.gridwidth = 2;
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ layout.setConstraints(value, c);
+ add(value);
+ }
+ }
+
+ public class Value {
+ JLabel label;
+ JTextField value;
+ void show(AltosState state, AltosListenerState listener_state) {}
+
+ void reset() {
+ value.setText("");
+ }
+
+ void show() {
+ label.setVisible(true);
+ value.setVisible(true);
+ }
+
+ void show(String s) {
+ show();
+ value.setText(s);
+ }
+
+ void show(AltosUnits units, double v) {
+ show(units.show(8, v));
+ }
+
+ void show(String format, double v) {
+ show(String.format(format, v));
+ }
+
+ void hide() {
+ label.setVisible(false);
+ value.setVisible(false);
+ }
+ void set_font() {
+ label.setFont(AltosUILib.label_font);
+ value.setFont(AltosUILib.value_font);
+ }
+
+ public Value (GridBagLayout layout, int y, String text) {
+ GridBagConstraints c = new GridBagConstraints();
+ c.weighty = 1;
+
+ label = new JLabel(text);
+ label.setFont(AltosUILib.label_font);
+ label.setHorizontalAlignment(SwingConstants.LEFT);
+ c.gridx = 1; c.gridy = y;
+ c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.VERTICAL;
+ c.weightx = 0;
+ layout.setConstraints(label, c);
+ add(label);
+
+ value = new JTextField(AltosUILib.text_width);
+ value.setFont(AltosUILib.value_font);
+ value.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = 2; c.gridy = y;
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.BOTH;
+ c.gridwidth = 2;
+ c.weightx = 1;
+ layout.setConstraints(value, c);
+ add(value);
+ }
+ }
+
+ public abstract class DualValue {
+ JLabel label;
+ JTextField value1;
+ JTextField value2;
+
+ void reset() {
+ value1.setText("");
+ value2.setText("");
+ }
+
+ void show() {
+ label.setVisible(true);
+ value1.setVisible(true);
+ value2.setVisible(true);
+ }
+
+ void hide() {
+ label.setVisible(false);
+ value1.setVisible(false);
+ value2.setVisible(false);
+ }
+
+ void set_font() {
+ label.setFont(AltosUILib.label_font);
+ value1.setFont(AltosUILib.value_font);
+ value2.setFont(AltosUILib.value_font);
+ }
+
+ abstract void show(AltosState state, AltosListenerState listener_state);
+
+ void show(String v1, String v2) {
+ show();
+ value1.setText(v1);
+ value2.setText(v2);
+ }
+ void show(String f1, double v1, String f2, double v2) {
+ show();
+ value1.setText(String.format(f1, v1));
+ value2.setText(String.format(f2, v2));
+ }
+
+ public DualValue (GridBagLayout layout, int x, int y, String text) {
+ GridBagConstraints c = new GridBagConstraints();
+ c.weighty = 1;
+
+ label = new JLabel(text);
+ label.setFont(AltosUILib.label_font);
+ label.setHorizontalAlignment(SwingConstants.LEFT);
+ c.gridx = x + 1; c.gridy = y;
+ c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.VERTICAL;
+ c.weightx = 0;
+ layout.setConstraints(label, c);
+ add(label);
+
+ value1 = new JTextField(AltosUILib.text_width);
+ value1.setFont(AltosUILib.value_font);
+ value1.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = x + 2; c.gridy = y;
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ layout.setConstraints(value1, c);
+ add(value1);
+
+ value2 = new JTextField(AltosUILib.text_width);
+ value2.setFont(AltosUILib.value_font);
+ value2.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = x + 3; c.gridy = y;
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ c.gridwidth = 1;
+ layout.setConstraints(value2, c);
+ add(value2);
+ }
+ }
+
+ public class ValueHold {
+ JLabel label;
+ JTextField value;
+ JTextField max_value;
+ double max;
+
+ void show(AltosState state, AltosListenerState listener_state) {}
+
+ void reset() {
+ value.setText("");
+ max_value.setText("");
+ max = AltosLib.MISSING;
+ }
+
+ void set_font() {
+ label.setFont(AltosUILib.label_font);
+ value.setFont(AltosUILib.value_font);
+ max_value.setFont(AltosUILib.value_font);
+ }
+
+ void show(AltosUnits units, double v) {
+ if (v == AltosLib.MISSING) {
+ value.setText("Missing");
+ max_value.setText("Missing");
+ } else {
+ value.setText(units.show(8, v));
+ if (v > max || max == AltosLib.MISSING) {
+ max_value.setText(units.show(8, v));
+ max = v;
+ }
+ }
+ }
+
+ void hide() {
+ label.setVisible(false);
+ value.setVisible(false);
+ max_value.setVisible(false);
+ }
+
+ public ValueHold (GridBagLayout layout, int y, String text) {
+ GridBagConstraints c = new GridBagConstraints();
+ c.weighty = 1;
+
+ label = new JLabel(text);
+ label.setFont(AltosUILib.label_font);
+ label.setHorizontalAlignment(SwingConstants.LEFT);
+ c.gridx = 1; c.gridy = y;
+ c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
+ c.anchor = GridBagConstraints.WEST;
+ c.fill = GridBagConstraints.VERTICAL;
+ c.weightx = 0;
+ layout.setConstraints(label, c);
+ add(label);
+
+ value = new JTextField(AltosUILib.text_width);
+ value.setFont(AltosUILib.value_font);
+ value.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = 2; c.gridy = y;
+ c.anchor = GridBagConstraints.EAST;
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ layout.setConstraints(value, c);
+ add(value);
+
+ max_value = new JTextField(AltosUILib.text_width);
+ max_value.setFont(AltosUILib.value_font);
+ max_value.setHorizontalAlignment(SwingConstants.RIGHT);
+ c.gridx = 3; c.gridy = y;
+ c.anchor = GridBagConstraints.EAST;
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ layout.setConstraints(max_value, c);
+ add(max_value);
+ }
+ }
+
+
+ class Altitude extends ValueHold {
+ void show (AltosState state, AltosListenerState listener_state) {
+ show(AltosConvert.height, state.altitude());
+ }
+ public Altitude (GridBagLayout layout, int y) {
+ super (layout, y, "Altitude");
+ }
+ }
+
+ Altitude altitude;
+
+ class AscentRate extends ValueHold {
+ void show (AltosState state, AltosListenerState listener_state) {
+ show(AltosConvert.speed, state.gps_ascent_rate());
+ }
+ public AscentRate (GridBagLayout layout, int y) {
+ super (layout, y, "Ascent Rate");
+ }
+ }
+
+ AscentRate ascent_rate;
+
+ class GroundSpeed extends ValueHold {
+ void show (AltosState state, AltosListenerState listener_state) {
+ show(AltosConvert.speed, state.gps_ground_speed());
+ }
+ public GroundSpeed (GridBagLayout layout, int y) {
+ super (layout, y, "Ground Speed");
+ }
+ }
+
+ GroundSpeed ground_speed;
+
+ String pos(double p, String pos, String neg) {
+ String h = pos;
+ if (p < 0) {
+ h = neg;
+ p = -p;
+ }
+ int deg = (int) Math.floor(p);
+ double min = (p - Math.floor(p)) * 60.0;
+ return String.format("%s %4d° %9.6f", h, deg, min);
+ }
+
+ class Course extends DualValue {
+ void show (AltosState state, AltosListenerState listener_state) {
+ double course = state.gps_course();
+ if (course != AltosLib.MISSING)
+ show( String.format("%3.0f°", course),
+ AltosConvert.bearing_to_words(
+ AltosConvert.BEARING_LONG,
+ course));
+ }
+ public Course (GridBagLayout layout, int y) {
+ super (layout, 0, y, "Course");
+ }
+ }
+
+ Course course;
+
+ class Lat extends Value {
+ void show (AltosState state, AltosListenerState listener_state) {
+ if (state.gps != null && state.gps.connected && state.gps.lat != AltosLib.MISSING)
+ show(pos(state.gps.lat,"N", "S"));
+ else
+ show("???");
+ }
+ public Lat (GridBagLayout layout, int y) {
+ super (layout, y, "Latitude");
+ }
+ }
+
+ Lat lat;
+
+ class Lon extends Value {
+ void show (AltosState state, AltosListenerState listener_state) {
+ if (state.gps != null && state.gps.connected && state.gps.lon != AltosLib.MISSING)
+ show(pos(state.gps.lon,"E", "W"));
+ else
+ show("???");
+ }
+ public Lon (GridBagLayout layout, int y) {
+ super (layout, y, "Longitude");
+ }
+ }
+
+ Lon lon;
+
+ class GPSLocked extends Info {
+ void show (AltosState state, AltosListenerState listener_state) {
+ if (state == null || state.gps == null)
+ hide();
+ else {
+ show("%4d sats", state.gps.nsat);
+ lights.set(state.gps.locked && state.gps.nsat >= 4);
+ }
+ }
+ public GPSLocked (GridBagLayout layout, int y) {
+ super (layout, y, "GPS Locked");
+ }
+ }
+
+ GPSLocked gps_locked;
+
+ public void reset() {
+ lat.reset();
+ lon.reset();
+ altitude.reset();
+ ground_speed.reset();
+ ascent_rate.reset();
+ course.reset();
+ gps_locked.reset();
+ }
+
+ public void set_font() {
+ cur.setFont(AltosUILib.label_font);
+ max.setFont(AltosUILib.label_font);
+ lat.set_font();
+ lon.set_font();
+ altitude.set_font();
+ ground_speed.set_font();
+ ascent_rate.set_font();
+ course.set_font();
+ gps_locked.set_font();
+ }
+
+ public void show(AltosState state, AltosListenerState listener_state) {
+ if (state.gps != null && state.gps.connected) {
+ lat.show(state, listener_state);
+ lon.show(state, listener_state);
+ } else {
+ lat.hide();
+ lon.hide();
+ }
+ altitude.show(state, listener_state);
+ ground_speed.show(state, listener_state);
+ ascent_rate.show(state, listener_state);
+ course.show(state, listener_state);
+ gps_locked.show(state, listener_state);
+ }
+
+ public void labels(GridBagLayout layout, int y) {
+ GridBagConstraints c;
+
+ cur = new JLabel("Current");
+ cur.setFont(AltosUILib.label_font);
+ c = new GridBagConstraints();
+ c.gridx = 2; c.gridy = y;
+ c.insets = new Insets(AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad, AltosUILib.tab_elt_pad);
+ layout.setConstraints(cur, c);
+ add(cur);
+
+ max = new JLabel("Maximum");
+ max.setFont(AltosUILib.label_font);
+ c.gridx = 3; c.gridy = y;
+ layout.setConstraints(max, c);
+ add(max);
+ }
+
+ public String getName() {
+ return "Info";
+ }
+
+ public TeleGPSInfo() {
+ layout = new GridBagLayout();
+
+ setLayout(layout);
+
+ /* Elements in ascent display:
+ *
+ * lat
+ * lon
+ * height
+ */
+ int y = 0;
+ labels(layout, y++);
+ altitude = new Altitude(layout, y++);
+ ground_speed = new GroundSpeed(layout, y++);
+ ascent_rate = new AscentRate(layout, y++);
+ course = new Course(layout, y++);
+ lat = new Lat(layout, y++);
+ lon = new Lon(layout, y++);
+ gps_locked = new GPSLocked(layout, y++);
+ }
+}