altosui: Add speed and gps height to map display data
authorKeith Packard <keithp@keithp.com>
Mon, 2 Sep 2019 20:20:14 +0000 (15:20 -0500)
committerKeith Packard <keithp@keithp.com>
Mon, 2 Sep 2019 20:45:30 +0000 (15:45 -0500)
And generalize the API so that any other GPS data could be added in
the future.

This feature was proposed by Mike Beattie

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosGPS.java
altoslib/AltosMap.java
altoslib/AltosMapPath.java
altoslib/AltosMapPathPoint.java
altoslib/AltosMapTransform.java
altosui/AltosGraphUI.java
altosuilib/AltosUIMap.java

index 8037eb9..57ac406 100644 (file)
@@ -92,6 +92,10 @@ public class AltosGPS implements Cloneable {
                return odt.toEpochSecond();
        }
 
+       public  AltosLatLon lat_lon() {
+               return new AltosLatLon(lat, lon);
+       }
+
        public AltosGPS(AltosTelemetryMap map) throws ParseException {
                String  state = map.get_string(AltosTelemetryLegacy.AO_TELEM_GPS_STATE,
                                               AltosTelemetryLegacy.AO_TELEM_GPS_STATE_ERROR);
index b9c4bfc..69142c3 100644 (file)
@@ -222,8 +222,7 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                return false;
        }
 
-       public void show(AltosGPS gps, double time, int state) {
-
+       public void show(AltosGPS gps, double time, int state, double gps_height) {
                /*
                 * If insufficient gps data, nothing to update
                 */
@@ -250,7 +249,7 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
                }
 
                if (path != null) {
-                       AltosMapRectangle       damage = path.add(gps.lat, gps.lon, time, state);
+                       AltosMapRectangle       damage = path.add(gps, time, state, gps_height);
 
                        if (damage != null)
                                repaint(damage, AltosMapPath.stroke_width);
@@ -262,7 +261,7 @@ public class AltosMap implements AltosMapTileListener, AltosMapStoreListener {
        }
 
        public void show(AltosState state, AltosListenerState listener_state) {
-               show(state.gps, state.time, state.state());
+               show(state.gps, state.time, state.state(), state.gps_height());
        }
 
        public void centre(AltosLatLon lat_lon) {
index 54ff51f..bbb6c99 100644 (file)
@@ -32,13 +32,13 @@ public abstract class AltosMapPath {
 
        public abstract void paint(AltosMapTransform t);
 
-       public AltosMapRectangle add(double lat, double lon, double time, int state) {
-               AltosMapPathPoint               point = new AltosMapPathPoint(new AltosLatLon (lat, lon), time, state);
+       public AltosMapRectangle add(AltosGPS gps, double time, int state, double gps_height) {
+               AltosMapPathPoint               point = new AltosMapPathPoint(gps, time, state, gps_height);
                AltosMapRectangle       rect = null;
 
                if (!point.equals(last_point)) {
                        if (last_point != null)
-                               rect = new AltosMapRectangle(last_point.lat_lon, point.lat_lon);
+                               rect = new AltosMapRectangle(last_point.gps.lat_lon(), point.gps.lat_lon());
                        points.add (point);
                        last_point = point;
                }
@@ -48,8 +48,8 @@ public abstract class AltosMapPath {
        private double dist(AltosLatLon lat_lon, AltosMapPathPoint point) {
                return (new AltosGreatCircle(lat_lon.lat,
                                             lat_lon.lon,
-                                            point.lat_lon.lat,
-                                            point.lat_lon.lon)).distance;
+                                            point.gps.lat,
+                                            point.gps.lon)).distance;
        }
 
        public AltosMapPathPoint nearest(AltosLatLon lat_lon) {
index c23d856..88a8bfc 100644 (file)
@@ -24,12 +24,13 @@ import java.util.*;
 import java.util.concurrent.*;
 
 public class AltosMapPathPoint {
-       public AltosLatLon      lat_lon;
+       public AltosGPS         gps;
        public double           time;
        public int              state;
+       public double           gps_height;
 
        public int hashCode() {
-               return lat_lon.hashCode() ^ state;
+               return Double.valueOf(gps.lat).hashCode() ^ Double.valueOf(gps.lon).hashCode() ^ state;
        }
 
        public boolean equals(Object o) {
@@ -41,13 +42,14 @@ public class AltosMapPathPoint {
 
                AltosMapPathPoint other = (AltosMapPathPoint) o;
 
-               return lat_lon.equals(other.lat_lon) && state == other.state;
+               return gps.lat == other.gps.lat && gps.lon == other.gps.lon && state == other.state;
        }
 
-       public AltosMapPathPoint(AltosLatLon lat_lon, double time, int state) {
-               this.lat_lon = lat_lon;
+       public AltosMapPathPoint(AltosGPS gps, double time, int state, double gps_height) {
+               this.gps = gps;
                this.time = time;
                this.state = state;
+               this.gps_height = gps_height;
        }
 }
 
index 6bc6c6f..9eac265 100644 (file)
@@ -67,13 +67,13 @@ public class AltosMapTransform {
                return lat_lon(screen_point(screen));
        }
 
-       public AltosPointDouble point(AltosLatLon lat_lon) {
+       public  AltosPointDouble point(double lat, double lon) {
                double x, y;
                double e;
 
-               x = lat_lon.lon * scale_x;
+               x = lon * scale_x;
 
-               e = Math.sin(Math.toRadians(lat_lon.lat));
+               e = Math.sin(Math.toRadians(lat));
                e = Math.max(e,-(1-1.0E-15));
                e = Math.min(e,  1-1.0E-15 );
 
@@ -82,6 +82,10 @@ public class AltosMapTransform {
                return new AltosPointDouble(x, y);
        }
 
+       public AltosPointDouble point(AltosLatLon lat_lon) {
+               return point(lat_lon.lat, lat_lon.lon);
+       }
+
        public AltosPointDouble screen(AltosPointDouble point) {
                return new AltosPointDouble(point.x - offset_x, point.y - offset_y);
        }
@@ -102,6 +106,10 @@ public class AltosMapTransform {
                return screen(point(lat_lon));
        }
 
+       public AltosPointDouble screen(double lat, double lon) {
+               return screen(point(lat, lon));
+       }
+
        private boolean has_location;
 
        public boolean has_location() {
index c1e18ac..c1fdc3a 100644 (file)
@@ -45,6 +45,7 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
        void fill_map(AltosFlightSeries flight_series) {
                boolean                 any_gps = false;
                AltosGPSTimeValue       gtv_last = null;
+               double gps_pad_altitude = flight_series.cal_data().gps_pad_altitude;;
 
                if (flight_series.gps_series != null) {
                        for (AltosGPSTimeValue gtv : flight_series.gps_series) {
@@ -54,7 +55,9 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                                    gps.nsat >= 4) {
                                        if (map == null)
                                                map = new AltosUIMap();
-                                       map.show(gps, gtv. time, (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time));
+                                       double gps_height = gps.alt - gps_pad_altitude;
+                                       int state = (int) flight_series.value_before(AltosFlightSeries.state_name, gtv.time);
+                                       map.show(gps, gtv.time, state, gps_height);
                                        this.gps = gps;
                                        gtv_last = gtv;
                                        has_gps = true;
@@ -63,8 +66,9 @@ public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, Alt
                }
                if (gtv_last != null) {
                        int state = (int) flight_series.value_after(AltosFlightSeries.state_name, gtv_last.time);
+                       double gps_height = gps.alt - gps_pad_altitude;
                        if (state == AltosLib.ao_flight_landed)
-                               map.show(gtv_last.gps, gtv_last.time, state);
+                               map.show(gtv_last.gps, gtv_last.time, state,gps_height);
                }
        }
 
index 6b78c35..5b981d1 100644 (file)
@@ -117,6 +117,8 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                }
 
                String pos(double p, String pos, String neg) {
+                       if (p == AltosLib.MISSING)
+                               return "";
                        String  h = pos;
                        if (p < 0) {
                                h = neg;
@@ -127,25 +129,44 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                        return String.format("%s %4d° %9.6f'", h, deg, min);
                }
 
+               String height(double h, String label) {
+                       if (h == AltosLib.MISSING)
+                               return "";
+                       return String.format(" %s%s",
+                                            AltosConvert.height.show(6, h),
+                                            label);
+               }
+
+               String speed(double s, String label) {
+                       if (s == AltosLib.MISSING)
+                               return "";
+                       return String.format(" %s%s",
+                                            AltosConvert.speed.show(6, s),
+                                            label);
+               }
+
                public void mouseMoved(MouseEvent e) {
                        AltosMapPathPoint point = map.nearest(e.getPoint().x, e.getPoint().y);
 
                        if (nearest_mark == null)
-                               nearest_mark = map.add_mark(point.lat_lon.lat,
-                                                           point.lat_lon.lon,
+                               nearest_mark = map.add_mark(point.gps.lat,
+                                                           point.gps.lon,
                                                            point.state);
                        else {
-                               nearest_mark.lat_lon.lat = point.lat_lon.lat;
-                               nearest_mark.lat_lon.lon = point.lat_lon.lon;
+                               nearest_mark.lat_lon.lat = point.gps.lat;
+                               nearest_mark.lat_lon.lon = point.gps.lon;
                                nearest_mark.state = point.state;
                        }
                        if (point != null) {
-                               nearest_label.setText(String.format("Time: %9.2f Position:  %s  %s",
+                               nearest_label.setText(String.format("%9.2f sec %s%s%s%s",
                                                                    point.time,
-                                                                   pos(point.lat_lon.lat,
+                                                                   pos(point.gps.lat,
                                                                        "N", "S"),
-                                                                   pos(point.lat_lon.lon,
-                                                                       "E", "W")));
+                                                                   pos(point.gps.lon,
+                                                                       "E", "W"),
+                                                                   height(point.gps_height, ""),
+                                                                   speed(point.gps.ground_speed, "(h)"),
+                                                                   speed(point.gps.climb_rate, "(v)")));
                        } else {
                                nearest_label.setText("");
                        }
@@ -256,7 +277,7 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                        g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
 
                        for (AltosMapPathPoint point : points) {
-                               Point2D.Double  cur = point2d(t.screen(point.lat_lon));
+                               Point2D.Double  cur = point2d(t.screen(point.gps.lat, point.gps.lon));
                                if (prev != null) {
                                        Line2D.Double   line = new Line2D.Double (prev, cur);
                                        Rectangle       bounds = line.getBounds();
@@ -468,8 +489,8 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
                map.show(state, listener_state);
        }
 
-       public void show(AltosGPS gps, double time, int state) {
-               map.show(gps, time, state);
+       public void show(AltosGPS gps, double time, int state, double gps_height) {
+               map.show(gps, time, state, gps_height);
        }
 
        public String getName() {