diff options
| -rw-r--r-- | altosuilib/AltosSiteMap.java | 166 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapCache.java | 2 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapImage.java | 7 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapPreload.java | 139 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapTile.java | 23 | 
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) | 
