summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-07-16 22:34:44 -0700
committerKeith Packard <keithp@keithp.com>2011-07-16 22:34:44 -0700
commit0a4d934f6e2914bfe2d965630543f029a1576c11 (patch)
tree4e8331d9c0edb19a10e8f9b5b6c6f949aadaca4d
parentabb8510b97ce9cbbff0275cc31f74780fe1ce138 (diff)
altosui: Display full map preload area in view.
This involved fixing the map view to support arbitrary sizes, and then exposing a synchronous tile loading API so that the progress bar could be used to show tile loading progress. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altosui/AltosSiteMap.java99
-rw-r--r--altosui/AltosSiteMapCache.java6
-rw-r--r--altosui/AltosSiteMapPreload.java91
-rw-r--r--altosui/AltosSiteMapTile.java8
4 files changed, 136 insertions, 68 deletions
diff --git a/altosui/AltosSiteMap.java b/altosui/AltosSiteMap.java
index 73068138..188902e9 100644
--- a/altosui/AltosSiteMap.java
+++ b/altosui/AltosSiteMap.java
@@ -97,6 +97,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
int zoom;
double scale_x, scale_y;
+ int radius; /* half width/height of tiles to load */
+
private Point2D.Double pt(double lat, double lng) {
return pt(new LatLng(lat, lng), scale_x, scale_y);
}
@@ -144,37 +146,31 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
// nothing
}
- private void bgLoadMap(final AltosSiteMapTile tile,
- final File pngfile, final String pngurl)
+ private void loadMap(final AltosSiteMapTile tile,
+ File pngfile, String pngurl)
{
- //System.out.printf("Loading/fetching map %s\n", pngfile);
- Thread thread = new Thread() {
- public void run() {
- final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl);
- if (res != null) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- tile.loadMap(res);
- }
- });
- } else {
- System.out.printf("# Failed to fetch file %s\n", pngfile);
- System.out.printf(" wget -O '%s' ''\n", pngfile, pngurl);
- }
- }
- };
- thread.start();
+ final ImageIcon res = AltosSiteMapCache.fetchAndLoadMap(pngfile, pngurl);
+ if (res != null) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ tile.loadMap(res);
+ }
+ });
+ } else {
+ System.out.printf("# Failed to fetch file %s\n", pngfile);
+ System.out.printf(" wget -O '%s' '%s'\n", pngfile, pngurl);
+ }
}
- File pngfile;
- String pngurl;
+ File pngfile;
+ String pngurl;
public int prefetchMap(int x, int y) {
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);
- pngurl = MapURL(map_latlng.lat, map_latlng.lng);
+ 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)) {
@@ -210,25 +206,41 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
}
}
- private void initMap(AltosSiteMapTile tile, Point offset) {
+ public String initMap(Point offset) {
+ AltosSiteMapTile tile = mapTiles.get(offset);
Point2D.Double coord = tileCoordOffset(offset);
LatLng map_latlng = latlng(px_size/2-coord.x, px_size/2-coord.y);
- File pngfile = MapFile(map_latlng.lat, map_latlng.lng);
- String pngurl = MapURL(map_latlng.lat, map_latlng.lng);
- bgLoadMap(tile, pngfile, pngurl);
+ File pngfile = MapFile(map_latlng.lat, map_latlng.lng, zoom);
+ String pngurl = MapURL(map_latlng.lat, map_latlng.lng, zoom);
+ loadMap(tile, pngfile, pngurl);
+ return pngfile.toString();
}
- private void initMaps(double lat, double lng) {
- centre = getBaseLocation(lat, lng);
-
+ public void setBaseLocation(double lat, double lng) {
for (Point k : mapTiles.keySet()) {
- initMap(mapTiles.get(k), k);
+ AltosSiteMapTile tile = mapTiles.get(k);
+ tile.clearMap();
}
+
+ centre = getBaseLocation(lat, lng);
+ scrollRocketToVisible(pt(lat,lng));
}
- private File MapFile(double lat, double lng) {
+ private void initMaps(double lat, double lng) {
+ setBaseLocation(lat, lng);
+
+ Thread thread = new Thread() {
+ public void run() {
+ for (Point k : mapTiles.keySet())
+ initMap(k);
+ }
+ };
+ thread.start();
+ }
+
+ private static File MapFile(double lat, double lng, int zoom) {
char chlat = lat < 0 ? 'S' : 'N';
char chlng = lng < 0 ? 'W' : 'E';
if (lat < 0) lat = -lat;
@@ -238,7 +250,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
chlat, lat, chlng, lng, zoom));
}
- private String MapURL(double lat, double lng) {
+ private static String MapURL(double lat, double lng, int zoom) {
return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&sensor=false&maptype=hybrid&format=png32", lat, lng, zoom, px_size, px_size);
}
@@ -248,7 +260,6 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
public void show(double lat, double lon) {
initMaps(lat, lon);
- initialised = true;
scrollRocketToVisible(pt(lat, lon));
}
public void show(final AltosState state, final int crc_errors) {
@@ -295,7 +306,7 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
AltosSiteMapTile tile = createTile(offset);
tile.show(state, crc_errors, lref, ref);
- initMap(tile, offset);
+ initMap(offset);
finishTileLater(tile, offset);
}
@@ -325,13 +336,13 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
}
private void ensureTilesAround(Point base_offset) {
- for (int x = -1; x <= 1; x++) {
- for (int y = -1; y <= 1; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ for (int y = -radius; y <= radius; y++) {
Point offset = new Point(base_offset.x + x, base_offset.y + y);
if (mapTiles.containsKey(offset))
continue;
AltosSiteMapTile tile = createTile(offset);
- initMap(tile, offset);
+ initMap(offset);
finishTileLater(tile, offset);
}
}
@@ -396,13 +407,15 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
JComponent comp = new JComponent() { };
private GridBagLayout layout = new GridBagLayout();
- public AltosSiteMap() {
+ public AltosSiteMap(int in_radius) {
+ radius = in_radius;
+
GrabNDrag scroller = new GrabNDrag(comp);
comp.setLayout(layout);
- for (int x = -1; x <= 1; x++) {
- for (int y = -1; y <= 1; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ for (int y = -radius; y <= radius; y++) {
Point offset = new Point(x, y);
AltosSiteMapTile t = createTile(offset);
addTileAt(t, offset);
@@ -411,4 +424,8 @@ public class AltosSiteMap extends JScrollPane implements AltosFlightDisplay {
setViewportView(comp);
setPreferredSize(new Dimension(500,500));
}
+
+ public AltosSiteMap() {
+ this(1);
+ }
}
diff --git a/altosui/AltosSiteMapCache.java b/altosui/AltosSiteMapCache.java
index 2e62cc45..cfad52a9 100644
--- a/altosui/AltosSiteMapCache.java
+++ b/altosui/AltosSiteMapCache.java
@@ -37,6 +37,7 @@ public class AltosSiteMapCache extends JLabel {
try {
u = new URL(url);
} catch (java.net.MalformedURLException e) {
+ System.out.printf("Malformed URL '%s'\n", url);
return false;
}
@@ -57,9 +58,12 @@ public class AltosSiteMapCache extends JLabel {
in.close();
if (offset != contentLength) {
+ System.out.printf("Bad length %d != %d\n",
+ offset, contentLength);
return false;
}
} catch (IOException e) {
+ System.out.printf("IO exception reading URL\n");
return false;
}
@@ -69,11 +73,13 @@ public class AltosSiteMapCache extends JLabel {
out.flush();
out.close();
} catch (FileNotFoundException e) {
+ System.out.printf("Can't create file\n");
return false;
} catch (IOException e) {
if (file.exists()) {
file.delete();
}
+ System.out.printf("IO exception writing file\n");
return false;
}
return true;
diff --git a/altosui/AltosSiteMapPreload.java b/altosui/AltosSiteMapPreload.java
index f939e9d6..25133435 100644
--- a/altosui/AltosSiteMapPreload.java
+++ b/altosui/AltosSiteMapPreload.java
@@ -33,6 +33,7 @@ import java.awt.geom.Point2D;
import java.awt.geom.Line2D;
class AltosMapPos extends Box {
+ AltosUI owner;
JLabel label;
JComboBox hemi;
JTextField deg;
@@ -58,25 +59,51 @@ class AltosMapPos extends Box {
public double get_value() throws NumberFormatException {
int h = hemi.getSelectedIndex();
- double d = Double.parseDouble(deg.getText());
- double m = Double.parseDouble(min.getText());
- double v = d + m/60.0;
+ String d_t = deg.getText();
+ String m_t = min.getText();
+ double d, m, v;
+ try {
+ d = Double.parseDouble(d_t);
+ } catch (NumberFormatException ne) {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Invalid degrees \"%s\"",
+ d_t),
+ "Invalid number",
+ JOptionPane.ERROR_MESSAGE);
+ throw ne;
+ }
+ try {
+ if (m_t.equals(""))
+ m = 0;
+ else
+ m = Double.parseDouble(m_t);
+ } catch (NumberFormatException ne) {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Invalid minutes \"%s\"",
+ m_t),
+ "Invalid number",
+ JOptionPane.ERROR_MESSAGE);
+ throw ne;
+ }
+ v = d + m/60.0;
if (h == 1)
v = -v;
return v;
}
- public AltosMapPos(String label_value,
+ public AltosMapPos(AltosUI 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.setEditable(false);
deg = new JTextField("000");
- deg_label = new JLabel("degrees");
+ deg_label = new JLabel("°");
min = new JTextField("00.0000");
- min_label = new JLabel("minutes");
+ min_label = new JLabel("'");
set_value(default_value);
add(label);
add(Box.createRigidArea(new Dimension(5, 0)));
@@ -101,9 +128,9 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
JProgressBar pbar;
- final static int width = 9;
- final static int height = 9;
- final static int tiles = width * height;
+ final static int radius = 4;
+ final static int width = (radius * 2 + 1);
+ final static int height = (radius * 2 + 1);
JToggleButton load_button;
boolean loading;
@@ -116,15 +143,21 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
int n;
String s;
- public updatePbar(int in_n, String in_s) {
- n = in_n;
+ public updatePbar(int x, int y, String in_s) {
+ n = (x + radius) + (y + radius) * width + 1;
+ System.out.printf("update pbar %d\n", n);
s = in_s;
}
public void run() {
pbar.setValue(n);
pbar.setString(s);
- if (n == width * height) {
+ if (n < width * height) {
+ pbar.setValue(n);
+ pbar.setString(s);
+ } else {
+ pbar.setValue(0);
+ pbar.setString("");
load_button.setSelected(false);
loading = false;
}
@@ -140,11 +173,11 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
}
public void run() {
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- map.prefetchMap(y - height/2, x - width/2);
- SwingUtilities.invokeLater(new updatePbar(y * height + x + 1,
- map.pngfile.toString()));
+ for (int y = -map.radius; y <= map.radius; y++) {
+ for (int x = -map.radius; x <= map.radius; x++) {
+ String pngfile;
+ pngfile = map.initMap(new Point(x,y));
+ SwingUtilities.invokeLater(new updatePbar(x, y, pngfile));
}
}
}
@@ -158,12 +191,16 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
if (cmd.equals("load")) {
if (!loading) {
- loading = true;
- final double latitude = lat.get_value();
- final double longitude = lon.get_value();
- map.show(latitude,longitude);
- bgLoad thread = new bgLoad(map);
- thread.start();
+ try {
+ final double latitude = lat.get_value();
+ final double longitude = lon.get_value();
+ map.setBaseLocation(latitude,longitude);
+ loading = true;
+ bgLoad thread = new bgLoad(map);
+ thread.start();
+ } catch (NumberFormatException ne) {
+ load_button.setSelected(false);
+ }
}
}
}
@@ -177,7 +214,7 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
pane.setLayout(new GridBagLayout());
- map = new AltosSiteMap();
+ map = new AltosSiteMap(4);
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
@@ -211,7 +248,8 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
pane.add(pbar, c);
- lat = new AltosMapPos("Latitude:",
+ lat = new AltosMapPos(owner,
+ "Latitude:",
lat_hemi_names,
37.167833333);
c.fill = GridBagConstraints.NONE;
@@ -227,7 +265,8 @@ public class AltosSiteMapPreload extends JDialog implements ActionListener {
pane.add(lat, c);
- lon = new AltosMapPos("Longitude:",
+ lon = new AltosMapPos(owner,
+ "Longitude:",
lon_hemi_names,
-97.73975);
diff --git a/altosui/AltosSiteMapTile.java b/altosui/AltosSiteMapTile.java
index 8301f42b..66da7c54 100644
--- a/altosui/AltosSiteMapTile.java
+++ b/altosui/AltosSiteMapTile.java
@@ -35,11 +35,16 @@ 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);
+ }
+
static Color stateColors[] = {
Color.WHITE, // startup
Color.WHITE, // idle
@@ -90,7 +95,8 @@ public class AltosSiteMapTile extends JLayeredPane {
return g;
}
- public AltosSiteMapTile(int px_size) {
+ public AltosSiteMapTile(int in_px_size) {
+ px_size = in_px_size;
setPreferredSize(new Dimension(px_size, px_size));
mapLabel = new JLabel();