diff options
| -rw-r--r-- | altosuilib/AltosSiteMap.java | 90 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapCache.java | 4 | ||||
| -rw-r--r-- | altosuilib/AltosSiteMapTile.java | 68 | ||||
| -rw-r--r-- | altosuilib/GrabNDrag.java | 21 | 
4 files changed, 166 insertions, 17 deletions
diff --git a/altosuilib/AltosSiteMap.java b/altosuilib/AltosSiteMap.java index f4143fe2..f22d9531 100644 --- a/altosuilib/AltosSiteMap.java +++ b/altosuilib/AltosSiteMap.java @@ -22,7 +22,7 @@ import java.awt.event.*;  import javax.swing.*;  import java.io.*;  import java.lang.Math; -import java.awt.geom.Point2D; +import java.awt.geom.*;  import java.util.*;  import java.util.concurrent.*;  import org.altusmetrum.altoslib_4.*; @@ -50,7 +50,7 @@ class MapPoint {  	}  } -public class AltosSiteMap extends JComponent implements AltosFlightDisplay { +public class AltosSiteMap extends JComponent implements AltosFlightDisplay, MouseMotionListener, MouseListener {  	// preferred vertical step in a tile in naut. miles  	// will actually choose a step size between x and 2x, where this  	// is 1.5x @@ -160,6 +160,10 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay {  	}  	*/ +	private LatLng latlng(Point pt) { +		return latlng(new Point2D.Double(pt.x, pt.y), scale_x, scale_y); +	} +  	ConcurrentHashMap<Point,AltosSiteMapTile> mapTiles = new ConcurrentHashMap<Point,AltosSiteMapTile>();  	Point2D.Double centre; @@ -307,16 +311,15 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay {  		base_location_set = false;  		circle_set = false;  		points = new LinkedList<MapPoint>(); -		for (AltosSiteMapTile tile : mapTiles.values()) -			tile.clearMap(); +		line_start = line_end = null;  	}  	public void setBaseLocation(double lat, double lng) { +		for (AltosSiteMapTile tile : mapTiles.values()) +			tile.clearMap();  		this.lat = lat;  		this.lon = lng;  		base_location_set = true; -		for (AltosSiteMapTile tile : mapTiles.values()) -			tile.clearMap();  		centre = getBaseLocation(lat, lng);  		scrollRocketToVisible(pt(lat,lng)); @@ -442,6 +445,8 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay {  		}  		if (circle_set)  			draw_circle(circle_lat, circle_lon); +		if (line_start != null) +			set_line();  	}  	public void show(final AltosState state, final AltosListenerState listener_state) { @@ -598,14 +603,85 @@ public class AltosSiteMap extends JComponent implements AltosFlightDisplay {  		}  	} -	JComponent comp = new JComponent() { }; +	JComponent comp; +  	private GridBagLayout layout = new GridBagLayout(); +	LatLng	line_start, line_end; + +	private void set_line() { +		if (line_start != null && line_end != null) { +			Point2D.Double	start = pt(line_start.lat, line_start.lng); +			Point2D.Double	end = pt(line_end.lat, line_end.lng); +			AltosGreatCircle	g = new AltosGreatCircle(line_start.lat, line_start.lng, +									 line_end.lat, line_end.lng); + +			for (Point offset : mapTiles.keySet()) { +				AltosSiteMapTile tile = mapTiles.get(offset); +				Point2D.Double s, e; +				s = translatePoint(start, tileCoordOffset(offset)); +				e = translatePoint(end, tileCoordOffset(offset)); +				tile.set_line(new Line2D.Double(s.x, s.y, e.x, e.y), g.distance); +			} +		} else { +			for (AltosSiteMapTile tile : mapTiles.values()) +				tile.set_line(null, 0); +		} +	} + +	LatLng latlng(MouseEvent e) { +		if (!base_location_set) +			return null; + +		Rectangle	zerozero = mapTiles.get(new Point(0, 0)).getBounds(); + +		return latlng(-centre.x + e.getPoint().x - zerozero.x, -centre.y + e.getPoint().y - zerozero.y); +	} + +	/* MouseMotionListener methods */ +	public void mouseDragged(MouseEvent e) { +		if (!GrabNDrag.grab_n_drag(e)) { +			LatLng	loc = latlng(e); +			line_end = loc; +			set_line(); +		} +	} + +	public void mouseMoved(MouseEvent e) { +	} + +	/* MouseListener methods */ +	public void mouseClicked(MouseEvent e) { +	} + +	public void mouseEntered(MouseEvent e) { +	} + +	public void mouseExited(MouseEvent e) { +	} + +	public void mousePressed(MouseEvent e) { +		if (!GrabNDrag.grab_n_drag(e)) { +			LatLng	loc = latlng(e); +			line_start = loc; +			line_end = null; +			set_line(); +		} +	} + +	public void mouseReleased(MouseEvent e) { +	} +  	JScrollPane	pane = new JScrollPane();  	public AltosSiteMap(int in_radius) {  		radius = in_radius; +		comp = new JComponent() { }; + +		comp.addMouseMotionListener(this); +		comp.addMouseListener(this); +  		GrabNDrag scroller = new GrabNDrag(comp);  		comp.setLayout(layout); diff --git a/altosuilib/AltosSiteMapCache.java b/altosuilib/AltosSiteMapCache.java index acc84ab0..42914deb 100644 --- a/altosuilib/AltosSiteMapCache.java +++ b/altosuilib/AltosSiteMapCache.java @@ -91,7 +91,7 @@ public class AltosSiteMapCache {  	static final int	bad_request = 3;  	static final int	forbidden = 4; -	public static synchronized boolean has_map(File file, String url) { +	public static boolean has_map(File file, String url) {  		return file.exists();  	} @@ -182,7 +182,7 @@ public class AltosSiteMapCache {  	static long			used; -	public static synchronized Image get_image(Component component, File file, int width, int height) { +	public static Image get_image(Component component, File file, int width, int height) {  		int		oldest = -1;  		long		age = used;  		AltosCacheImage	image; diff --git a/altosuilib/AltosSiteMapTile.java b/altosuilib/AltosSiteMapTile.java index 9610b248..09f184a3 100644 --- a/altosuilib/AltosSiteMapTile.java +++ b/altosuilib/AltosSiteMapTile.java @@ -44,6 +44,9 @@ public class AltosSiteMapTile extends JComponent {  	Point2D.Double	boost;  	Point2D.Double	landed; +	Line2D.Double	line; +	double		line_course; +	double		line_dist;  	LinkedList<AltosPoint>	points; @@ -81,6 +84,7 @@ public class AltosSiteMapTile extends JComponent {  		file = null;  		status = AltosSiteMapCache.success;  		queue_repaint(); +		line = null;  	}  	static Color stateColors[] = { @@ -106,6 +110,47 @@ public class AltosSiteMapTile extends JComponent {  		queue_repaint();  	} +	public void set_line(Line2D.Double line, double distance) { +		this.line = line; +		line_dist = distance; +		queue_repaint(); +	} + +	private String line_dist() { +		String	format; +		double	distance = line_dist; + +		if (AltosConvert.imperial_units) { +			distance = AltosConvert.meters_to_feet(distance); +			if (distance < 10000) { +				format = "%4.0fft"; +			} else { +				distance /= 5280; +				if (distance < 10) +					format = "%5.3fmi"; +				else if (distance < 100) +					format = "%5.2fmi"; +				else if (distance < 1000) +					format = "%5.1fmi"; +				else +					format = "%5.0fmi"; +			} +		} else { +			if (distance < 10000) { +				format = "%4.0fm"; +			} else { +				distance /= 1000; +				if (distance < 100) +					format = "%5.2fkm"; +				else if (distance < 1000) +					format = "%5.1fkm"; +				else +					format = "%5.0fkm"; +			} +		} +		return String.format(format, distance); +	} +  	public void paint(Graphics g) {  		Graphics2D	g2d = (Graphics2D) g;  		AltosPoint	prev = null; @@ -143,7 +188,7 @@ public class AltosSiteMapTile extends JComponent {  				float x = getWidth() / 2.0f;  				float y = getHeight() / 2.0f;  				x = x - (float) bounds.getWidth() / 2.0f; -				y = y - (float) bounds.getHeight() / 2.0f; +				y = y + (float) bounds.getHeight() / 2.0f;  				g2d.setColor(Color.BLACK);  				g2d.drawString(message, x, y);  			} @@ -171,6 +216,27 @@ public class AltosSiteMapTile extends JComponent {  			g2d.setColor(Color.BLACK);  			draw_circle(g2d, landed);  		} + +		if (line != null) { +			g2d.setColor(Color.BLUE); +			g2d.draw(line); + +			String	message = line_dist(); +			g2d.setFont(font); +			g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); +			Rectangle2D	bounds; +			bounds = font.getStringBounds(message, g2d.getFontRenderContext()); + +			float x = (float) line.x1; +			float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f; + +			if (line.x1 < line.x2) { +				x -= (float) bounds.getWidth() + 2.0f; +			} else { +				x += 2.0f; +			} +			g2d.drawString(message, x, y); +		}  	}  	public synchronized void show(int state, Point2D.Double last_pt, Point2D.Double pt) diff --git a/altosuilib/GrabNDrag.java b/altosuilib/GrabNDrag.java index 5e5fdd52..4426f7a3 100644 --- a/altosuilib/GrabNDrag.java +++ b/altosuilib/GrabNDrag.java @@ -33,16 +33,23 @@ class GrabNDrag extends MouseInputAdapter {  		scroll.setAutoscrolls(true);  	} +	public static boolean grab_n_drag(MouseEvent e) { +		return e.getModifiers() == InputEvent.BUTTON1_MASK; +	} +  	public void mousePressed(MouseEvent e) { -		startPt.setLocation(e.getPoint()); +		if (grab_n_drag(e)) +			startPt.setLocation(e.getPoint());  	}  	public void mouseDragged(MouseEvent e) { -		int xd = e.getX() - startPt.x; -		int yd = e.getY() - startPt.y; +		if (grab_n_drag(e)) { +			int xd = e.getX() - startPt.x; +			int yd = e.getY() - startPt.y; -		Rectangle r = scroll.getVisibleRect(); -		r.x -= xd; -		r.y -= yd; -		scroll.scrollRectToVisible(r); +			Rectangle r = scroll.getVisibleRect(); +			r.x -= xd; +			r.y -= yd; +			scroll.scrollRectToVisible(r); +		}  	}  }  | 
