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.*;
}
}
-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
}
*/
+ 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;
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));
}
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) {
}
}
- 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);
Point2D.Double boost;
Point2D.Double landed;
+ Line2D.Double line;
+ double line_course;
+ double line_dist;
LinkedList<AltosPoint> points;
file = null;
status = AltosSiteMapCache.success;
queue_repaint();
+ line = null;
}
static Color stateColors[] = {
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;
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);
}
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)
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);
+ }
}
}