summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-05-28 10:16:38 -0700
committerKeith Packard <keithp@keithp.com>2014-05-28 10:16:38 -0700
commit52ce41952c5a3c31532fa4f0d1b3155a162b76f4 (patch)
tree91d72fd602969a74b7d1ec0cc6c67fd298313c25
parent5c3991768d3cb17fc99ad32b2d6d8d11f0e37dfa (diff)
altosuilib: Update map preloading UI to include zoom and maptypes
This lets you specify precisely which maps to load. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altosuilib/AltosSiteMap.java166
-rw-r--r--altosuilib/AltosSiteMapCache.java2
-rw-r--r--altosuilib/AltosSiteMapImage.java7
-rw-r--r--altosuilib/AltosSiteMapPreload.java139
-rw-r--r--altosuilib/AltosSiteMapTile.java23
5 files changed, 245 insertions, 92 deletions
diff --git a/altosuilib/AltosSiteMap.java b/altosuilib/AltosSiteMap.java
index d9ea564c..461886c7 100644
--- a/altosuilib/AltosSiteMap.java
+++ b/altosuilib/AltosSiteMap.java
@@ -74,7 +74,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
"terrain"
};
- static final String[] maptype_labels = {
+ public static final String[] maptype_labels = {
"Hybrid",
"Roadmap",
"Satellite",
@@ -240,7 +240,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
String pngurl;
}
- public AltosSiteMapPrefetch prefetchMap(int x, int y) {
+ private AltosSiteMapPrefetch prefetchMap(int x, int y) {
AltosSiteMapPrefetch prefetch = new AltosSiteMapPrefetch();
LatLng map_latlng = latlng(
-centre.x + x*px_size + px_size/2,
@@ -257,28 +257,34 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
return prefetch;
}
- public static void prefetchMaps(double lat, double lng) {
- int w = AltosSiteMapPreload.width;
- int h = AltosSiteMapPreload.height;
+ public static void prefetchMaps(double lat, double lng, int radius, int maptypes, int min_zoom, int max_zoom) {
AltosSiteMap asm = new AltosSiteMap(true);
- asm.centre = asm.getBaseLocation(lat, lng);
-
- int dx = -w/2, dy = -h/2;
- for (int y = dy; y < h+dy; y++) {
- for (int x = dx; x < w+dx; x++) {
- AltosSiteMapPrefetch prefetch = asm.prefetchMap(x, y);
- switch (prefetch.result) {
- case 1:
- System.out.printf("Already have %s\n", prefetch.pngfile);
- break;
- case 0:
- System.out.printf("Fetched map %s\n", prefetch.pngfile);
- break;
- case -1:
- System.out.printf("# Failed to fetch file %s\n", prefetch.pngfile);
- System.out.printf(" wget -O '%s' ''\n",
- prefetch.pngfile, prefetch.pngurl);
- break;
+
+ for (int z = min_zoom; z <= max_zoom; z++) {
+ asm.zoom = z;
+ asm.set_radius(radius);
+ asm.centre = asm.getBaseLocation(lat, lng);
+ for (int t = maptype_hybrid; t <= maptype_terrain; t++) {
+ if ((maptypes & (1 << t)) !=0) {
+ asm.maptype = t;
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ AltosSiteMapPrefetch prefetch = asm.prefetchMap(x, y);
+ switch (prefetch.result) {
+ case 1:
+ System.out.printf("Already have %s\n", prefetch.pngfile);
+ break;
+ case 0:
+ System.out.printf("Fetched map %s\n", prefetch.pngfile);
+ break;
+ case -1:
+ System.out.printf("# Failed to fetch file %s\n", prefetch.pngfile);
+ System.out.printf(" wget -O '%s' ''\n",
+ prefetch.pngfile, prefetch.pngurl);
+ break;
+ }
+ }
+ }
}
}
}
@@ -296,7 +302,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
return pngfile;
}
- public void initAndFinishMapAsync (final AltosSiteMapTile tile, final Point offset) {
+ private void initAndFinishMapAsync (final AltosSiteMapTile tile, final Point offset) {
Thread thread = new Thread() {
public void run() {
init_map(offset, load_mode_cached|load_mode_uncached);
@@ -318,6 +324,10 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
circle_set = false;
points = new LinkedList<MapPoint>();
line_start = line_end = null;
+ for (AltosSiteMapTile tile : mapTiles.values()) {
+ tile.clearMap();
+ tile.set_status(AltosSiteMapCache.loading);
+ }
}
public void setBaseLocation(double lat, double lng) {
@@ -382,7 +392,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
MapPoint last_point = null;
int last_state = -1;
- public void show(double lat, double lon) {
+ private void show(double lat, double lon) {
System.out.printf ("show %g %g\n", lat, lon);
return;
// initMaps(lat, lon);
@@ -391,15 +401,17 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
JLabel zoom_label;
- public void set_zoom_label() {
+ private void set_zoom_label() {
zoom_label.setText(String.format("Zoom %d", zoom - default_zoom));
}
public void set_zoom(int zoom) {
if (min_zoom <= zoom && zoom <= max_zoom) {
this.zoom = zoom;
- if (base_location_set)
+ if (base_location_set) {
+ set_tiles();
initMaps(lat, lon);
+ }
redraw();
set_zoom_label();
}
@@ -409,7 +421,15 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
return zoom;
}
- public void draw(MapPoint last_point, MapPoint point) {
+ public void set_maptype(int type) {
+ maptype = type;
+ maptype_combo.setSelectedIndex(type);
+ if (base_location_set)
+ initMaps(lat, lon);
+ redraw();
+ }
+
+ private void draw(MapPoint last_point, MapPoint point) {
boolean force_ensure = false;
if (last_point == null) {
force_ensure = true;
@@ -449,7 +469,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
}
}
- public void redraw() {
+ private void redraw() {
MapPoint last_point = null;
for (MapPoint point : points) {
@@ -496,7 +516,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
last_point = point;
}
- public void centre(Point2D.Double pt) {
+ private void centre(Point2D.Double pt) {
Rectangle r = comp.getVisibleRect();
Point2D.Double copt = translatePoint(pt, tileCoordOffset(topleft));
int dx = (int)copt.x - r.width/2 - r.x;
@@ -508,7 +528,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
comp.scrollRectToVisible(r);
}
- public void centre(AltosState state) {
+ private void centre(AltosState state) {
if (!state.gps.locked && state.gps.nsat < 4)
return;
centre(pt(state.gps.lat, state.gps.lon));
@@ -550,6 +570,32 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
}
}
+ private void set_tiles() {
+ for (int x = -radius; x <= radius; x++) {
+ for (int y = -radius; y <= radius; y++) {
+ Point offset = new Point(x, y);
+ if (mapTiles.containsKey(offset))
+ continue;
+ AltosSiteMapTile t = createTile(offset);
+ addTileAt(t, offset);
+ }
+ }
+ for (Point offset : mapTiles.keySet()) {
+ if (offset.x < -radius || offset.x > radius ||
+ offset.y < -radius || offset.y > radius)
+ {
+ removeTileAt(offset);
+ }
+ }
+ }
+
+ public void set_radius(int radius) {
+ if (radius != this.radius) {
+ this.radius = radius;
+ set_tiles();
+ }
+ }
+
private Point topleft = new Point(0,0);
private void scrollRocketToVisible(Point2D.Double pt) {
Rectangle r = comp.getVisibleRect();
@@ -573,18 +619,11 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
return;
}
- boolean review = false;
- Rectangle r = comp.getVisibleRect();
- if (offset.x < topleft.x) {
- r.x += (topleft.x - offset.x) * px_size;
+ if (offset.x < topleft.x)
topleft.x = offset.x;
- review = true;
- }
- if (offset.y < topleft.y) {
- r.y += (topleft.y - offset.y) * px_size;
+ if (offset.y < topleft.y)
topleft.y = offset.y;
- review = true;
- }
+
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.BOTH;
@@ -596,9 +635,6 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
layout.setConstraints(tile, c);
comp.add(tile);
-// if (review) {
-// comp.scrollRectToVisible(r);
-// }
}
private AltosSiteMap(boolean knowWhatYouAreDoing) {
@@ -607,6 +643,21 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
}
}
+ private void removeTileAt(Point offset) {
+ AltosSiteMapTile tile = mapTiles.get(offset);
+
+ mapTiles.remove(offset);
+ comp.remove(tile);
+
+ topleft = new Point(MAX_TILE_DELTA, MAX_TILE_DELTA);
+ for (Point o : mapTiles.keySet()) {
+ if (o.x < topleft.x)
+ topleft.x = o.x;
+ if (o.y < topleft.y)
+ topleft.y = o.y;
+ }
+ }
+
JComponent comp;
private GridBagLayout layout = new GridBagLayout();
@@ -634,11 +685,13 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
}
static void debug_component(Component who, String where) {
-// Rectangle r = who.getBounds();
-// int x = r.x / px_size;
-// int y = r.y / px_size;
-//
-// System.out.printf ("%3d, %3d: %s\n", x, y, where);
+/*
+ Rectangle r = who.getBounds();
+ int x = r.x / px_size;
+ int y = r.y / px_size;
+
+ System.out.printf ("%3d, %3d: %s\n", x, y, where);
+*/
}
LatLng latlng(MouseEvent e) {
@@ -684,7 +737,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
public void mouseReleased(MouseEvent e) {
}
- public void set_cache_size() {
+ private void set_cache_size() {
Rectangle r = comp.getVisibleRect();
int width_tiles = (r.width + 2*px_size) / px_size;
@@ -704,6 +757,8 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
JScrollPane pane = new JScrollPane();
+ JComboBox<String> maptype_combo;
+
public AltosSiteMap(int in_radius) {
radius = in_radius;
@@ -717,13 +772,8 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
comp.setLayout(layout);
- 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);
- }
- }
+ set_tiles();
+
pane.setViewportView(comp);
pane.setPreferredSize(new Dimension(500,500));
pane.setVisible(true);
@@ -805,7 +855,7 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay, Mous
c.weighty = 0;
add(zoom_out, c);
- final JComboBox<String> maptype_combo = new JComboBox<String>(maptype_labels);
+ maptype_combo = new JComboBox<String>(maptype_labels);
maptype_combo.setEditable(false);
maptype_combo.setMaximumRowCount(maptype_combo.getItemCount());
diff --git a/altosuilib/AltosSiteMapCache.java b/altosuilib/AltosSiteMapCache.java
index 7f436ef0..3e08e1b3 100644
--- a/altosuilib/AltosSiteMapCache.java
+++ b/altosuilib/AltosSiteMapCache.java
@@ -176,6 +176,7 @@ public class AltosSiteMapCache {
return new Point (x, y);
}
+/*
private static void dump_cache() {
int min_x = 1000, max_x = -1000, min_y = 1000, max_y = -1000;
@@ -208,6 +209,7 @@ public class AltosSiteMapCache {
System.out.printf("\n");
}
}
+*/
public static AltosSiteMapImage get_image(AltosSiteMapTile tile, File file, int width, int height) {
int oldest = -1;
diff --git a/altosuilib/AltosSiteMapImage.java b/altosuilib/AltosSiteMapImage.java
index f08c0b26..ae32418f 100644
--- a/altosuilib/AltosSiteMapImage.java
+++ b/altosuilib/AltosSiteMapImage.java
@@ -34,7 +34,7 @@ public class AltosSiteMapImage {
Thread load_thread;
- public boolean validate() {
+ public boolean validate(final int serial) {
if (image != null) {
AltosSiteMap.debug_component(tile, "valid");
return true;
@@ -42,16 +42,15 @@ public class AltosSiteMapImage {
AltosSiteMap.debug_component(tile, "loading");
load_thread = new Thread() {
public void run() {
- image = null;
try {
image = ImageIO.read(file);
} catch (Exception e) {
}
SwingUtilities.invokeLater( new Runnable() {
public void run() {
- AltosSiteMap.debug_component(tile, "later");
+ AltosSiteMap.debug_component(tile, file.toString());
Graphics2D g2d = (Graphics2D) tile.getGraphics();
- tile.paint_graphics(g2d, image);
+ tile.paint_graphics(g2d, image, serial);
load_thread = null;
}
});
diff --git a/altosuilib/AltosSiteMapPreload.java b/altosuilib/AltosSiteMapPreload.java
index 107b09f8..6b8066b3 100644
--- a/altosuilib/AltosSiteMapPreload.java
+++ b/altosuilib/AltosSiteMapPreload.java
@@ -206,18 +206,15 @@ class AltosSites extends Thread {
}
}
-public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener, ItemListener {
+public class AltosSiteMapPreload extends AltosUIFrame implements ActionListener, ItemListener {
AltosUIFrame owner;
AltosSiteMap map;
AltosMapPos lat;
AltosMapPos lon;
- final static int radius = 5;
- final static int width = (radius * 2 + 1);
- final static int height = (radius * 2 + 1);
-
JProgressBar pbar;
+ int pbar_max;
AltosSites sites;
JLabel site_list_label;
@@ -227,6 +224,15 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
boolean loading;
JButton close_button;
+ JCheckBox[] maptypes = new JCheckBox[AltosSiteMap.maptype_terrain - AltosSiteMap.maptype_hybrid + 1];
+
+ JComboBox<Integer> min_zoom;
+ JComboBox<Integer> max_zoom;
+ JComboBox<Integer> radius;
+
+ Integer[] zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
+ Integer[] radii = { 1, 2, 3, 4, 5 };
+
static final String[] lat_hemi_names = { "N", "S" };
static final String[] lon_hemi_names = { "E", "W" };
@@ -234,15 +240,16 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
int n;
String s;
- public updatePbar(int x, int y, String in_s) {
- n = (x + radius) + (y + radius) * width + 1;
+ public updatePbar(int n, String in_s) {
+ this.n = n;
s = in_s;
}
public void run() {
pbar.setValue(n);
pbar.setString(s);
- if (n < width * height) {
+ if (n < pbar_max) {
+ pbar.setMaximum(pbar_max);
pbar.setValue(n);
pbar.setString(s);
} else {
@@ -258,17 +265,54 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
AltosSiteMap map;
- public bgLoad(AltosSiteMap in_map) {
+ double lat, lon;
+
+ int types = 0;
+ int r;
+
+ int min_z = (Integer) min_zoom.getSelectedItem();
+ int max_z = (Integer) max_zoom.getSelectedItem();
+
+ public bgLoad(AltosSiteMap in_map, double lat, double lon) {
map = in_map;
+ this.lat = lat;
+ this.lon = lon;
+ if (max_z < min_z)
+ max_z = min_z;
+ int ntype = 0;
+ for (int t = AltosSiteMap.maptype_hybrid; t <= AltosSiteMap.maptype_terrain; t++)
+ if (maptypes[t].isSelected()) {
+ types |= (1 << t);
+ ntype++;
+ }
+ if (ntype == 0) {
+ types |= (1 << AltosSiteMap.maptype_hybrid);
+ ntype = 1;
+ }
+ r = (Integer) radius.getSelectedItem();
+ pbar_max = (max_z - min_z + 1) * ntype * (r * 2 + 1) * (r * 2 + 1);
}
public void run() {
- for (int y = -map.radius; y <= map.radius; y++) {
- for (int x = -map.radius; x <= map.radius; x++) {
- File pngfile;
- pngfile = map.init_map(new Point(x,y),
- AltosSiteMap.load_mode_cached|AltosSiteMap.load_mode_uncached);
- SwingUtilities.invokeLater(new updatePbar(x, y, pngfile.toString()));
+ int i = 0;
+ for (int z = min_z; z <= max_z; z++) {
+ for (int t = AltosSiteMap.maptype_hybrid; t <= AltosSiteMap.maptype_terrain; t++) {
+ if ((types & (1 << t)) == 0)
+ continue;
+ map.clear_base_location();
+ map.set_zoom(z + AltosSiteMap.default_zoom);
+ map.set_maptype(t);
+ map.set_radius(r);
+ map.setBaseLocation(lat, lon);
+ map.draw_circle(lat, lon);
+ for (int y = -r; y <= r; y++) {
+ for (int x = -r; x <= r; x++) {
+ File pngfile;
+ pngfile = map.init_map(new Point(x,y),
+ AltosSiteMap.load_mode_cached|AltosSiteMap.load_mode_uncached);
+ SwingUtilities.invokeLater(new updatePbar(++i, pngfile.toString()));
+ }
+ }
}
}
}
@@ -310,7 +354,7 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
map.setBaseLocation(latitude,longitude);
map.draw_circle(latitude,longitude);
loading = true;
- bgLoad thread = new bgLoad(map);
+ bgLoad thread = new bgLoad(map, latitude, longitude);
thread.start();
} catch (NumberFormatException ne) {
load_button.setSelected(false);
@@ -326,9 +370,11 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
GridBagConstraints c = new GridBagConstraints();
Insets i = new Insets(4,4,4,4);
+ setTitle("AltOS Load Maps");
+
pane.setLayout(new GridBagLayout());
- map = new AltosSiteMap(radius);
+ map = new AltosSiteMap(2);
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
@@ -338,14 +384,14 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
c.gridx = 0;
c.gridy = 0;
- c.gridwidth = 2;
+ c.gridwidth = 10;
c.anchor = GridBagConstraints.CENTER;
pane.add(map, c);
pbar = new JProgressBar();
pbar.setMinimum(0);
- pbar.setMaximum(width * height);
+ pbar.setMaximum(1);
pbar.setValue(0);
pbar.setString("");
pbar.setStringPainted(true);
@@ -358,7 +404,7 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
c.gridx = 0;
c.gridy = 1;
- c.gridwidth = 2;
+ c.gridwidth = 10;
pane.add(pbar, c);
@@ -462,6 +508,59 @@ public class AltosSiteMapPreload extends AltosUIDialog implements ActionListener
pane.add(close_button, c);
+ JLabel types_label = new JLabel("Map Types");
+ c.gridx = 2;
+ c.gridwidth = 2;
+ c.gridy = 2;
+ pane.add(types_label, c);
+
+ c.gridwidth = 1;
+
+ for (int type = AltosSiteMap.maptype_hybrid; type <= AltosSiteMap.maptype_terrain; type++) {
+ maptypes[type] = new JCheckBox(AltosSiteMap.maptype_labels[type],
+ type == AltosSiteMap.maptype_hybrid);
+ c.gridx = 2 + (type >> 1);
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridy = (type & 1) + 3;
+ pane.add(maptypes[type], c);
+ }
+
+ JLabel min_zoom_label = new JLabel("Minimum Zoom");
+ c.gridx = 4;
+ c.gridy = 2;
+ pane.add(min_zoom_label, c);
+
+ min_zoom = new JComboBox<Integer>(zooms);
+ min_zoom.setSelectedItem(zooms[10]);
+ min_zoom.setEditable(false);
+ c.gridx = 5;
+ c.gridy = 2;
+ pane.add(min_zoom, c);
+
+ JLabel max_zoom_label = new JLabel("Maximum Zoom");
+ c.gridx = 4;
+ c.gridy = 3;
+ pane.add(max_zoom_label, c);
+
+ max_zoom = new JComboBox<Integer>(zooms);
+ max_zoom.setSelectedItem(zooms[14]);
+ max_zoom.setEditable(false);
+ c.gridx = 5;
+ c.gridy = 3;
+ pane.add(max_zoom, c);
+
+ JLabel radius_label = new JLabel("Tile Radius");
+ c.gridx = 4;
+ c.gridy = 4;
+ pane.add(radius_label, c);
+
+ radius = new JComboBox<Integer>(radii);
+ radius.setSelectedItem(radii[4]);
+ radius.setEditable(false);
+ c.gridx = 5;
+ c.gridy = 4;
+ pane.add(radius, c);
+
pack();
setLocationRelativeTo(owner);
setVisible(true);
diff --git a/altosuilib/AltosSiteMapTile.java b/altosuilib/AltosSiteMapTile.java
index 136fbd7a..f8b924a8 100644
--- a/altosuilib/AltosSiteMapTile.java
+++ b/altosuilib/AltosSiteMapTile.java
@@ -155,9 +155,16 @@ public class AltosSiteMapTile extends JComponent {
return String.format(format, distance);
}
- boolean painting;
+ int painting_serial;
+ int painted_serial;
+
+ public void paint_graphics(Graphics2D g2d, Image image, int serial) {
+
+ if (serial < painted_serial)
+ return;
+
+ painted_serial = serial;
- public void paint_graphics(Graphics2D g2d, Image image) {
if (image != null) {
AltosSiteMap.debug_component(this, "paint_graphics");
g2d.drawImage(image, 0, 0, null);
@@ -239,7 +246,6 @@ public class AltosSiteMapTile extends JComponent {
}
g2d.drawString(message, x, y);
}
- painting = false;
}
public void paint(Graphics g) {
@@ -247,26 +253,23 @@ public class AltosSiteMapTile extends JComponent {
Image image = null;
boolean queued = false;
- if (painting) {
- AltosSiteMap.debug_component(this, "already painting");
- return;
- }
AltosSiteMap.debug_component(this, "paint");
+ ++painting_serial;
+
if (file != null) {
AltosSiteMapImage aimage;
aimage = AltosSiteMapCache.get_image(this, file, px_size, px_size);
if (aimage != null) {
- if (aimage.validate())
+ if (aimage.validate(painting_serial))
image = aimage.image;
else
queued = true;
}
}
if (!queued)
- paint_graphics(g2d, image);
- painting = queued;
+ paint_graphics(g2d, image, painting_serial);
}
public void show(int state, Point2D.Double last_pt, Point2D.Double pt)