summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-05-25 20:55:11 -0700
committerKeith Packard <keithp@keithp.com>2014-05-25 20:56:48 -0700
commit0a6c76fc0525d6588a1d88127f0085f13a02f1af (patch)
treed7cf76748c86522708b0826237eb031f371e349d
parent4ac7797d3efb9cc2d9fae88519f55e40b1050224 (diff)
altosui/altosuilib/altoslib: Move more stuff out of autosui. Reduce site map memory
Prepare to share with TeleGPS application. This also has the changes to the site map tile which cache only a few images and regenerate the flight path on the fly, saving piles of memory Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altoslib/AltosFlightStats.java (renamed from altosui/AltosFlightStats.java)63
-rw-r--r--altoslib/Makefile.am3
-rw-r--r--altosui/AltosSiteMapTile.java122
-rw-r--r--altosui/Makefile.am12
-rw-r--r--altosuilib/AltosDisplayThread.java (renamed from altosui/AltosDisplayThread.java)28
-rw-r--r--altosuilib/AltosFlightDisplay.java (renamed from altosui/AltosFlightDisplay.java)4
-rw-r--r--altosuilib/AltosFreqList.java (renamed from altosui/AltosFreqList.java)7
-rw-r--r--altosuilib/AltosSiteMap.java (renamed from altosui/AltosSiteMap.java)56
-rw-r--r--altosuilib/AltosSiteMapCache.java (renamed from altosui/AltosSiteMapCache.java)115
-rw-r--r--altosuilib/AltosSiteMapPreload.java (renamed from altosui/AltosSiteMapPreload.java)22
-rw-r--r--altosuilib/AltosSiteMapTile.java142
-rw-r--r--altosuilib/AltosVoice.java (renamed from altosui/AltosVoice.java)3
-rw-r--r--altosuilib/GrabNDrag.java (renamed from altosui/GrabNDrag.java)2
-rw-r--r--altosuilib/Makefile.am13
14 files changed, 346 insertions, 246 deletions
diff --git a/altosui/AltosFlightStats.java b/altoslib/AltosFlightStats.java
index d02a518d..87e04293 100644
--- a/altosui/AltosFlightStats.java
+++ b/altoslib/AltosFlightStats.java
@@ -15,41 +15,40 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altoslib_4;
import java.io.*;
-import org.altusmetrum.altoslib_3.*;
public class AltosFlightStats {
- double max_height;
- double max_gps_height;
- double max_speed;
- double max_acceleration;
- double[] state_speed = new double[Altos.ao_flight_invalid + 1];
- double[] state_accel = new double[Altos.ao_flight_invalid + 1];
- int[] state_count = new int[Altos.ao_flight_invalid + 1];
- double[] state_start = new double[Altos.ao_flight_invalid + 1];
- double[] state_end = new double[Altos.ao_flight_invalid + 1];
- int serial;
- int flight;
- int year, month, day;
- int hour, minute, second;
- double lat, lon;
- double pad_lat, pad_lon;
- boolean has_gps;
- boolean has_other_adc;
- boolean has_rssi;
- boolean has_imu;
- boolean has_mag;
- boolean has_orient;
- int num_ignitor;
+ public double max_height;
+ public double max_gps_height;
+ public double max_speed;
+ public double max_acceleration;
+ public double[] state_speed = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_accel = new double[AltosLib.ao_flight_invalid + 1];
+ public int[] state_count = new int[AltosLib.ao_flight_invalid + 1];
+ public double[] state_start = new double[AltosLib.ao_flight_invalid + 1];
+ public double[] state_end = new double[AltosLib.ao_flight_invalid + 1];
+ public int serial;
+ public int flight;
+ public int year, month, day;
+ public int hour, minute, second;
+ public double lat, lon;
+ public double pad_lat, pad_lon;
+ public boolean has_gps;
+ public boolean has_other_adc;
+ public boolean has_rssi;
+ public boolean has_imu;
+ public boolean has_mag;
+ public boolean has_orient;
+ public int num_ignitor;
double landed_time(AltosStateIterable states) {
AltosState state = null;
for (AltosState s : states) {
state = s;
- if (state.state == Altos.ao_flight_landed)
+ if (state.state == AltosLib.ao_flight_landed)
break;
}
@@ -128,10 +127,10 @@ public class AltosFlightStats {
end_time = state.time;
int state_id = state.state;
- if (state.time >= boost_time && state_id < Altos.ao_flight_boost)
- state_id = Altos.ao_flight_boost;
- if (state.time >= landed_time && state_id < Altos.ao_flight_landed)
- state_id = Altos.ao_flight_landed;
+ if (state.time >= boost_time && state_id < AltosLib.ao_flight_boost)
+ state_id = AltosLib.ao_flight_boost;
+ if (state.time >= landed_time && state_id < AltosLib.ao_flight_landed)
+ state_id = AltosLib.ao_flight_landed;
if (state.gps != null && state.gps.locked) {
year = state.gps.year;
month = state.gps.month;
@@ -140,7 +139,7 @@ public class AltosFlightStats {
minute = state.gps.minute;
second = state.gps.second;
}
- if (0 <= state_id && state_id < Altos.ao_flight_invalid) {
+ if (0 <= state_id && state_id < AltosLib.ao_flight_invalid) {
double acceleration = state.acceleration();
double speed = state.speed();
if (acceleration != AltosLib.MISSING && speed != AltosLib.MISSING) {
@@ -158,7 +157,7 @@ public class AltosFlightStats {
max_gps_height = state.max_gps_height();
}
if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
- if (state_id <= Altos.ao_flight_pad) {
+ if (state_id <= AltosLib.ao_flight_pad) {
pad_lat = state.gps.lat;
pad_lon = state.gps.lon;
}
@@ -175,7 +174,7 @@ public class AltosFlightStats {
if (state.ignitor_voltage != null && state.ignitor_voltage.length > num_ignitor)
num_ignitor = state.ignitor_voltage.length;
}
- for (int s = Altos.ao_flight_startup; s <= Altos.ao_flight_landed; s++) {
+ for (int s = AltosLib.ao_flight_startup; s <= AltosLib.ao_flight_landed; s++) {
if (state_count[s] > 0) {
state_speed[s] /= state_count[s];
state_accel[s] /= state_count[s];
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index 67cc38ff..bff09704 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -1,4 +1,4 @@
-AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
JAVAROOT=bin
@@ -51,6 +51,7 @@ altoslib_JAVA = \
AltosFlash.java \
AltosFlashListener.java \
AltosFlightReader.java \
+ AltosFlightStats.java \
AltosFrequency.java \
AltosGPS.java \
AltosGPSSat.java \
diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java
deleted file mode 100644
index 7d5b65e1..00000000
--- a/altosui/AltosSiteMapTile.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
- *
- * 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.awt.*;
-import java.awt.image.*;
-import javax.swing.*;
-import java.awt.geom.Point2D;
-import java.awt.geom.Line2D;
-import org.altusmetrum.altoslib_3.*;
-
-public class AltosSiteMapTile extends JLayeredPane {
- JLabel mapLabel;
- JLabel draw;
- Graphics2D g2d;
- int px_size;
-
- public void loadMap(ImageIcon icn) {
- mapLabel.setIcon(icn);
- }
-
- public void clearMap() {
- fillLabel(mapLabel, Color.GRAY, px_size);
- g2d = fillLabel(draw, new Color(127,127,127,0), px_size);
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g2d.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- }
-
- static Color stateColors[] = {
- Color.WHITE, // startup
- Color.WHITE, // idle
- Color.WHITE, // pad
- Color.RED, // boost
- Color.PINK, // fast
- Color.YELLOW, // coast
- Color.CYAN, // drogue
- Color.BLUE, // main
- Color.BLACK // landed
- };
-
- private boolean drawn_landed_circle = false;
- private boolean drawn_boost_circle = false;
- public synchronized void show(AltosState state, AltosListenerState listener_state,
- Point2D.Double last_pt, Point2D.Double pt)
- {
- if (0 <= state.state && state.state < stateColors.length) {
- g2d.setColor(stateColors[state.state]);
- }
- g2d.draw(new Line2D.Double(last_pt, pt));
-
- if (state.state == 3 && !drawn_boost_circle) {
- drawn_boost_circle = true;
- g2d.setColor(Color.RED);
- g2d.drawOval((int)last_pt.x-5, (int)last_pt.y-5, 10, 10);
- g2d.drawOval((int)last_pt.x-20, (int)last_pt.y-20, 40, 40);
- g2d.drawOval((int)last_pt.x-35, (int)last_pt.y-35, 70, 70);
- }
- if (state.state == 8 && !drawn_landed_circle) {
- drawn_landed_circle = true;
- g2d.setColor(Color.BLACK);
- g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
- g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
- g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
- }
-
- repaint();
- }
-
- public void draw_circle(Point2D.Double pt) {
- g2d.setColor(Color.RED);
- g2d.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
- g2d.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
- g2d.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
- }
-
- public static Graphics2D fillLabel(JLabel l, Color c, int px_size) {
- BufferedImage img = new BufferedImage(px_size, px_size,
- BufferedImage.TYPE_INT_ARGB);
- Graphics2D g = img.createGraphics();
- g.setColor(c);
- g.fillRect(0, 0, px_size, px_size);
- l.setIcon(new ImageIcon(img));
- return g;
- }
-
- public AltosSiteMapTile(int in_px_size) {
- px_size = in_px_size;
- setPreferredSize(new Dimension(px_size, px_size));
-
- mapLabel = new JLabel();
- fillLabel(mapLabel, Color.GRAY, px_size);
- mapLabel.setOpaque(true);
- mapLabel.setBounds(0, 0, px_size, px_size);
- add(mapLabel, new Integer(0));
-
- draw = new JLabel();
- g2d = fillLabel(draw, new Color(127, 127, 127, 0), px_size);
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g2d.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- draw.setBounds(0, 0, px_size, px_size);
- draw.setOpaque(false);
-
- add(draw, new Integer(1));
- }
-}
diff --git a/altosui/Makefile.am b/altosui/Makefile.am
index 76fe9961..0440b4af 100644
--- a/altosui/Makefile.am
+++ b/altosui/Makefile.am
@@ -1,6 +1,6 @@
JAVAROOT=classes
-AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
man_MANS=altosui.1
@@ -17,7 +17,6 @@ altosui_BT = \
AltosBTKnown.java
altosui_JAVA = \
- GrabNDrag.java \
AltosAscent.java \
AltosChannelMenu.java \
AltosCompanionInfo.java \
@@ -31,20 +30,16 @@ altosui_JAVA = \
AltosCSVUI.java \
AltosDescent.java \
AltosDeviceUIDialog.java \
- AltosDisplayThread.java \
AltosEepromDelete.java \
AltosEepromManage.java \
AltosEepromMonitorUI.java \
AltosEepromSelect.java \
AltosFlashUI.java \
- AltosFlightDisplay.java \
AltosFlightInfoTableModel.java \
- AltosFlightStats.java \
AltosFlightStatsTable.java \
AltosFlightStatus.java \
AltosFlightStatusUpdate.java \
AltosFlightUI.java \
- AltosFreqList.java \
Altos.java \
AltosIdleMonitorUI.java \
AltosIgniteUI.java \
@@ -61,17 +56,12 @@ altosui_JAVA = \
AltosScanUI.java \
AltosSerial.java \
AltosSerialInUseException.java \
- AltosSiteMap.java \
- AltosSiteMapPreload.java \
- AltosSiteMapCache.java \
- AltosSiteMapTile.java \
AltosUI.java \
AltosGraph.java \
AltosGraphDataPoint.java \
AltosGraphDataSet.java \
AltosGraphUI.java \
AltosDataChooser.java \
- AltosVoice.java \
$(altosui_BT)
JFREECHART_CLASS= \
diff --git a/altosui/AltosDisplayThread.java b/altosuilib/AltosDisplayThread.java
index ab85607d..e88a891e 100644
--- a/altosui/AltosDisplayThread.java
+++ b/altosuilib/AltosDisplayThread.java
@@ -15,13 +15,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_3.*;
+import org.altusmetrum.altoslib_4.*;
public class AltosDisplayThread extends Thread {
@@ -78,7 +78,7 @@ public class AltosDisplayThread extends Thread {
return;
/* reset the landing count once we hear about a new flight */
- if (state.state < Altos.ao_flight_drogue)
+ if (state.state < AltosLib.ao_flight_drogue)
reported_landing = 0;
/* Shut up once the rocket is on the ground */
@@ -87,8 +87,8 @@ public class AltosDisplayThread extends Thread {
}
/* If the rocket isn't on the pad, then report height */
- if (Altos.ao_flight_drogue <= state.state &&
- state.state < Altos.ao_flight_landed &&
+ if (AltosLib.ao_flight_drogue <= state.state &&
+ state.state < AltosLib.ao_flight_landed &&
state.from_pad != null &&
state.range >= 0)
{
@@ -99,7 +99,7 @@ public class AltosDisplayThread extends Thread {
(int) (state.from_pad.bearing + 0.5),
(int) (state.elevation + 0.5),
AltosConvert.distance.say(state.range));
- } else if (state.state > Altos.ao_flight_pad) {
+ } else if (state.state > AltosLib.ao_flight_pad) {
voice.speak(AltosConvert.height.say_units(state.height()));
} else {
reported_landing = 0;
@@ -109,10 +109,10 @@ public class AltosDisplayThread extends Thread {
* either we've got a landed report or we haven't heard from it in
* a long time
*/
- if (state.state >= Altos.ao_flight_drogue &&
+ if (state.state >= AltosLib.ao_flight_drogue &&
(last ||
System.currentTimeMillis() - state.received_time >= 15000 ||
- state.state == Altos.ao_flight_landed))
+ state.state == AltosLib.ao_flight_landed))
{
if (Math.abs(state.speed()) < 20 && state.height() < 100)
voice.speak("rocket landed safely");
@@ -123,8 +123,8 @@ public class AltosDisplayThread extends Thread {
(int) (state.from_pad.bearing + 0.5),
AltosConvert.distance.say_units(state.from_pad.distance));
++reported_landing;
- if (state.state != Altos.ao_flight_landed) {
- state.state = Altos.ao_flight_landed;
+ if (state.state != AltosLib.ao_flight_landed) {
+ state.state = AltosLib.ao_flight_landed;
show_safely();
}
}
@@ -183,13 +183,13 @@ public class AltosDisplayThread extends Thread {
boolean ret = false;
if (old_state == null || old_state.state != state.state) {
voice.speak(state.state_name());
- if ((old_state == null || old_state.state <= Altos.ao_flight_boost) &&
- state.state > Altos.ao_flight_boost) {
+ if ((old_state == null || old_state.state <= AltosLib.ao_flight_boost) &&
+ state.state > AltosLib.ao_flight_boost) {
voice.speak("max speed: %s.",
AltosConvert.speed.say_units(state.max_speed() + 0.5));
ret = true;
- } else if ((old_state == null || old_state.state < Altos.ao_flight_drogue) &&
- state.state >= Altos.ao_flight_drogue) {
+ } else if ((old_state == null || old_state.state < AltosLib.ao_flight_drogue) &&
+ state.state >= AltosLib.ao_flight_drogue) {
voice.speak("max height: %s.",
AltosConvert.height.say_units(state.max_height() + 0.5));
ret = true;
diff --git a/altosui/AltosFlightDisplay.java b/altosuilib/AltosFlightDisplay.java
index c1264259..5695a015 100644
--- a/altosui/AltosFlightDisplay.java
+++ b/altosuilib/AltosFlightDisplay.java
@@ -15,9 +15,9 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
-import org.altusmetrum.altoslib_3.*;
+import org.altusmetrum.altoslib_4.*;
public interface AltosFlightDisplay {
void reset();
diff --git a/altosui/AltosFreqList.java b/altosuilib/AltosFreqList.java
index 525e5ce5..e1299aae 100644
--- a/altosui/AltosFreqList.java
+++ b/altosuilib/AltosFreqList.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 org.altusmetrum.altoslib_3.*;
-import org.altusmetrum.altosuilib_1.*;
+import org.altusmetrum.altoslib_4.*;
-public class AltosFreqList extends JComboBox {
+public class AltosFreqList extends JComboBox<AltosFrequency> {
String product;
int serial;
diff --git a/altosui/AltosSiteMap.java b/altosuilib/AltosSiteMap.java
index 643417b5..1cfbc8b5 100644
--- a/altosui/AltosSiteMap.java
+++ b/altosuilib/AltosSiteMap.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.*;
@@ -23,8 +23,7 @@ import java.io.*;
import java.lang.Math;
import java.awt.geom.Point2D;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_3.*;
-import org.altusmetrum.altosuilib_1.*;
+import org.altusmetrum.altoslib_4.*;
public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
// preferred vertical step in a tile in naut. miles
@@ -149,13 +148,13 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
}
private void loadMap(final AltosSiteMapTile tile,
- File pngfile, String pngurl)
+ final File pngfile, String pngurl)
{
- final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl);
- if (res != null) {
+ boolean loaded = AltosSiteMapCache.fetchMap(pngfile, pngurl);
+ if (loaded) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- tile.loadMap(res);
+ tile.loadMap(pngfile);
}
});
} else {
@@ -164,22 +163,30 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
}
}
- File pngfile;
- String pngurl;
- public int prefetchMap(int x, int y) {
+ class AltosSiteMapPrefetch {
+ int x;
+ int y;
+ int result;
+ File pngfile;
+ String pngurl;
+ }
+
+ public AltosSiteMapPrefetch prefetchMap(int x, int y) {
+ AltosSiteMapPrefetch prefetch = new AltosSiteMapPrefetch();
LatLng map_latlng = latlng(
-centre.x + x*px_size + px_size/2,
-centre.y + y*px_size + px_size/2);
- pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom);
- pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom);
- if (pngfile.exists()) {
- return 1;
- } else if (AltosSiteMapCache.fetchMap(pngfile, pngurl)) {
- return 0;
+ prefetch.pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom);
+ prefetch.pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom);
+ if (prefetch.pngfile.exists()) {
+ prefetch.result = 1;
+ } else if (AltosSiteMapCache.fetchMap(prefetch.pngfile, prefetch.pngurl)) {
+ prefetch.result = 0;
} else {
- return -1;
+ prefetch.result = -1;
}
+ return prefetch;
}
public static void prefetchMaps(double lat, double lng) {
@@ -193,17 +200,18 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
int dx = -w/2, dy = -h/2;
for (int y = dy; y < h+dy; y++) {
for (int x = dx; x < w+dx; x++) {
- int r = asm.prefetchMap(x, y);
- switch (r) {
+ AltosSiteMapPrefetch prefetch = asm.prefetchMap(x, y);
+ switch (prefetch.result) {
case 1:
- System.out.printf("Already have %s\n", asm.pngfile);
+ System.out.printf("Already have %s\n", prefetch.pngfile);
break;
case 0:
- System.out.printf("Fetched map %s\n", asm.pngfile);
+ System.out.printf("Fetched map %s\n", prefetch.pngfile);
break;
case -1:
- System.out.printf("# Failed to fetch file %s\n", asm.pngfile);
- System.out.printf(" wget -O '%s' ''\n", asm.pngfile, asm.pngurl);
+ System.out.printf("# Failed to fetch file %s\n", prefetch.pngfile);
+ System.out.printf(" wget -O '%s' ''\n",
+ prefetch.pngfile, prefetch.pngurl);
break;
}
}
@@ -362,7 +370,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
for (Point offset : mapTiles.keySet()) {
AltosSiteMapTile tile = mapTiles.get(offset);
Point2D.Double ref = translatePoint(pt, tileCoordOffset(offset));
- tile.draw_circle(ref);
+ tile.set_boost(ref);
}
}
diff --git a/altosui/AltosSiteMapCache.java b/altosuilib/AltosSiteMapCache.java
index 03dc3cf5..cf93016a 100644
--- a/altosui/AltosSiteMapCache.java
+++ b/altosuilib/AltosSiteMapCache.java
@@ -15,21 +15,79 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.image.*;
+import java.awt.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
+
+class AltosCacheImage {
+ Component component;
+ File file;
+ VolatileImage image;
+ int width;
+ int height;
+ long used;
+
+ public void load_image() throws IOException {
+ BufferedImage bimg = ImageIO.read(file);
+ Graphics2D g = image.createGraphics();
+ g.drawImage(bimg, 0, 0, null);
+ bimg.flush();
+ }
+
+ public Image validate() {
+ int returnCode;
+
+ if (image != null)
+ returnCode = image.validate(component.getGraphicsConfiguration());
+ else
+ returnCode = VolatileImage.IMAGE_INCOMPATIBLE;
+ if (returnCode == VolatileImage.IMAGE_RESTORED) {
+ try {
+ load_image();
+ } catch (IOException e) {
+ return null;
+ }
+ } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
+ image = component.createVolatileImage(width, height);
+ try {
+ load_image();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return image;
+ }
+
+ public void flush() {
+ image.flush();
+ }
+
+ public AltosCacheImage(Component component, File file, int w, int h) throws IOException {
+ this.component = component;
+ this.file = file;
+ width = w;
+ height = h;
+ image = component.createVolatileImage(w, h);
+ used = 0;
+ }
+}
+
public class AltosSiteMapCache extends JLabel {
static final long google_maps_ratelimit_ms = 1200;
// Google limits static map queries to 50 per minute per IP, so
// each query should take at least 1.2 seconds.
public static boolean fetchMap(File file, String url) {
+ if (file.exists())
+ return true;
+
URL u;
long startTime = System.nanoTime();
@@ -88,31 +146,48 @@ public class AltosSiteMapCache extends JLabel {
return true;
}
- public static ImageIcon fetchAndLoadMap(File pngfile, String url) {
- if (!pngfile.exists()) {
- if (!fetchMap(pngfile, url)) {
- return null;
- }
- }
- return loadMap(pngfile, url);
+ static int cache_size = 9;
+
+ static AltosCacheImage[] images;
+
+ static long used;
+
+ public static void set_cache_size(int cache_size) {
+ AltosSiteMapCache.cache_size = cache_size;
+ images = null;
}
- public static ImageIcon loadMap(File pngfile, String url) {
- if (!pngfile.exists()) {
- return null;
+ public static Image get_image(Component component, File file, int width, int height) {
+ int oldest = -1;
+ long age = used;
+ AltosCacheImage image;
+ if (images == null)
+ images = new AltosCacheImage[cache_size];
+ for (int i = 0; i < cache_size; i++) {
+ image = images[i];
+
+ if (image == null) {
+ oldest = i;
+ break;
+ }
+ if (image.component == component && file.equals(image.file)) {
+ image.used = used++;
+ return image.validate();
+ }
+ if (image.used < age) {
+ oldest = i;
+ age = image.used;
+ }
}
try {
- BufferedImage img;
-
- img = ImageIO.read(pngfile);
- if (img == null) {
- System.out.printf("# Can't read pngfile %s\n", pngfile);
- return null;
- }
- return new ImageIcon(img);
+ image = new AltosCacheImage(component, file, width, height);
+ image.used = used++;
+ if (images[oldest] != null)
+ images[oldest].flush();
+ images[oldest] = image;
+ return image.validate();
} catch (IOException e) {
- System.out.printf("# IO error trying to load %s\n", pngfile);
return null;
}
}
diff --git a/altosui/AltosSiteMapPreload.java b/altosuilib/AltosSiteMapPreload.java
index 8380b967..baa7fc37 100644
--- a/altosui/AltosSiteMapPreload.java
+++ b/altosuilib/AltosSiteMapPreload.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 java.awt.event.*;
@@ -26,10 +26,10 @@ import java.text.*;
import java.lang.Math;
import java.net.URL;
import java.net.URLConnection;
-import org.altusmetrum.altosuilib_1.*;
+import org.altusmetrum.altoslib_4.*;
class AltosMapPos extends Box {
- AltosUI owner;
+ AltosUIFrame owner;
JLabel label;
JComboBox hemi;
JTextField deg;
@@ -87,14 +87,14 @@ class AltosMapPos extends Box {
return v;
}
- public AltosMapPos(AltosUI in_owner,
+ public AltosMapPos(AltosUIFrame in_owner,
String label_value,
String[] hemi_names,
double default_value) {
super(BoxLayout.X_AXIS);
owner = in_owner;
label = new JLabel(label_value);
- hemi = new JComboBox(hemi_names);
+ hemi = new JComboBox<String>(hemi_names);
hemi.setEditable(false);
deg = new JTextField(5);
deg.setMinimumSize(deg.getPreferredSize());
@@ -179,7 +179,7 @@ class AltosSites extends Thread {
URLConnection uc = url.openConnection();
//int length = uc.getContentLength();
- InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), Altos.unicode_set);
+ InputStreamReader in_stream = new InputStreamReader(uc.getInputStream(), AltosLib.unicode_set);
BufferedReader in = new BufferedReader(in_stream);
for (;;) {
@@ -198,7 +198,7 @@ class AltosSites extends Thread {
sites = new LinkedList<AltosSite>();
preload = in_preload;
try {
- url = new URL(Altos.launch_sites_url);
+ url = new URL(AltosLib.launch_sites_url);
} catch (java.net.MalformedURLException e) {
notify_complete();
}
@@ -207,7 +207,7 @@ class AltosSites extends Thread {
}
public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener, ItemListener {
- AltosUI owner;
+ AltosUIFrame owner;
AltosSiteMap map;
AltosMapPos lat;
@@ -221,7 +221,7 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
AltosSites sites;
JLabel site_list_label;
- JComboBox site_list;
+ JComboBox<AltosSite> site_list;
JToggleButton load_button;
boolean loading;
@@ -317,7 +317,7 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
}
}
- public AltosSiteMapPreload(AltosUI in_owner) {
+ public AltosSiteMapPreload(AltosUIFrame in_owner) {
owner = in_owner;
Container pane = getContentPane();
@@ -374,7 +374,7 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
pane.add(site_list_label, c);
- site_list = new JComboBox(new String[] { "Site List" });
+ site_list = new JComboBox<AltosSite>(new AltosSite[] { new AltosSite("Site List", 0, 0) });
site_list.addItemListener(this);
sites = new AltosSites(this);
diff --git a/altosuilib/AltosSiteMapTile.java b/altosuilib/AltosSiteMapTile.java
new file mode 100644
index 00000000..1046d6bd
--- /dev/null
+++ b/altosuilib/AltosSiteMapTile.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
+ *
+ * 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.altosuilib_2;
+
+import java.awt.*;
+import java.awt.image.*;
+import javax.swing.*;
+import javax.imageio.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Line2D;
+import java.io.*;
+import java.util.*;
+import org.altusmetrum.altoslib_4.*;
+
+class AltosPoint {
+ Point2D.Double pt;
+ int state;
+
+ AltosPoint(Point2D.Double pt, int state) {
+ this.pt = pt;
+ this.state = state;
+ }
+}
+
+public class AltosSiteMapTile extends JComponent {
+ int px_size;
+ File file;
+
+ Point2D.Double boost;
+ Point2D.Double landed;
+
+ LinkedList<AltosPoint> points;
+
+ public void loadMap(File pngFile) {
+ file = pngFile;
+ repaint();
+ }
+
+ public void clearMap() {
+ boost = null;
+ landed = null;
+ points = null;
+ file = null;
+ }
+
+ static Color stateColors[] = {
+ Color.WHITE, // startup
+ Color.WHITE, // idle
+ Color.WHITE, // pad
+ Color.RED, // boost
+ Color.PINK, // fast
+ Color.YELLOW, // coast
+ Color.CYAN, // drogue
+ Color.BLUE, // main
+ Color.BLACK // landed
+ };
+
+ private void draw_circle(Graphics g, Point2D.Double pt) {
+ g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
+ g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
+ g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
+ }
+
+ public void set_boost(Point2D.Double boost) {
+ this.boost = boost;
+ repaint();
+ }
+
+ public void paint(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g;
+ AltosPoint prev = null;
+ Image img = null;
+
+ if (file != null)
+ img = AltosSiteMapCache.get_image(this, file, px_size, px_size);
+
+ if (img != null) {
+ g2d.drawImage(img, 0, 0, null);
+ } else {
+ g2d.setColor(Color.GRAY);
+ g2d.fillRect(0, 0, getWidth(), getHeight());
+ }
+
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+
+ if (points != null) {
+ for (AltosPoint point : points) {
+ if (prev != null) {
+ if (0 <= point.state && point.state < stateColors.length)
+ g2d.setColor(stateColors[point.state]);
+ g2d.draw(new Line2D.Double(prev.pt, point.pt));
+ }
+ prev = point;
+ }
+ }
+ if (boost != null) {
+ g2d.setColor(Color.RED);
+ draw_circle(g2d, boost);
+ }
+ if (landed != null) {
+ g2d.setColor(Color.BLACK);
+ draw_circle(g2d, landed);
+ }
+ }
+
+ public synchronized void show(AltosState state, AltosListenerState listener_state,
+ Point2D.Double last_pt, Point2D.Double pt)
+ {
+ if (points == null)
+ points = new LinkedList<AltosPoint>();
+
+ points.add(new AltosPoint(pt, state.state));
+
+ if (state.state == AltosLib.ao_flight_boost && boost == null)
+ boost = pt;
+ if (state.state == AltosLib.ao_flight_landed && landed == null)
+ landed = pt;
+ repaint();
+ }
+
+ public AltosSiteMapTile(int in_px_size) {
+ px_size = in_px_size;
+ setPreferredSize(new Dimension(px_size, px_size));
+ }
+}
diff --git a/altosui/AltosVoice.java b/altosuilib/AltosVoice.java
index 2ed6a8c2..a3995f68 100644
--- a/altosui/AltosVoice.java
+++ b/altosuilib/AltosVoice.java
@@ -15,12 +15,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package altosui;
+package org.altusmetrum.altosuilib_2;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altosuilib_1.*;
public class AltosVoice implements Runnable {
VoiceManager voice_manager;
diff --git a/altosui/GrabNDrag.java b/altosuilib/GrabNDrag.java
index 2fd6c4da..5e5fdd52 100644
--- a/altosui/GrabNDrag.java
+++ b/altosuilib/GrabNDrag.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 java.awt.event.*;
diff --git a/altosuilib/Makefile.am b/altosuilib/Makefile.am
index 4b22af1f..b7d624e2 100644
--- a/altosuilib/Makefile.am
+++ b/altosuilib/Makefile.am
@@ -1,4 +1,4 @@
-AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -source 6
+AM_JAVACFLAGS=-target 1.6 -encoding UTF-8 -Xlint:deprecation -Xlint:unchecked -source 6
JAVAROOT=bin
@@ -9,8 +9,10 @@ SRC=.
altosuilibdir = $(datadir)/java
altosuilib_JAVA = \
+ GrabNDrag.java \
AltosDevice.java \
AltosDeviceDialog.java \
+ AltosFlightDisplay.java \
AltosFontListener.java \
AltosPositionListener.java \
AltosUIConfigure.java \
@@ -30,7 +32,14 @@ altosuilib_JAVA = \
AltosUIPreferences.java \
AltosUISeries.java \
AltosUIVersion.java \
- AltosUSBDevice.java
+ AltosUSBDevice.java \
+ AltosSiteMap.java \
+ AltosSiteMapCache.java \
+ AltosSiteMapPreload.java \
+ AltosSiteMapTile.java \
+ AltosVoice.java \
+ AltosDisplayThread.java \
+ AltosFreqList.java
JAR=altosuilib_$(ALTOSUILIB_VERSION).jar