X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=altosuilib%2FAltosUIMap.java;h=aaa68f238c893549641585858a12dc291bff6ce0;hb=debian;hp=8c90bcd8d8a86ddd7549da7b90ec93ab669e9aaa;hpb=4d57c8b87f29f23beb0d88f1cef179209b1c5992;p=fw%2Faltos diff --git a/altosuilib/AltosUIMap.java b/altosuilib/AltosUIMap.java index 8c90bcd8..0a80959f 100644 --- a/altosuilib/AltosUIMap.java +++ b/altosuilib/AltosUIMap.java @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,7 +16,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altosuilib_11; +package org.altusmetrum.altosuilib_14; import java.awt.*; import java.awt.event.*; @@ -27,7 +28,7 @@ import java.awt.geom.*; import java.util.*; import java.util.concurrent.*; import javax.imageio.*; -import org.altusmetrum.altoslib_11.*; +import org.altusmetrum.altoslib_14.*; public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface { @@ -35,6 +36,7 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM Graphics2D g; Font tile_font; Font line_font; + AltosMapMark nearest_mark; static Point2D.Double point2d(AltosPointDouble pt) { return new Point2D.Double(pt.x, pt.y); @@ -46,20 +48,48 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM class MapMark extends AltosMapMark { public void paint(AltosMapTransform t) { - AltosPointDouble pt = t.screen(lat_lon); - - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); - - if (0 <= state && state < AltosUIMap.stateColors.length) - g.setColor(AltosUIMap.stateColors[state]); - else - g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]); + double lat = lat_lon.lat; + double lon; + double first_lon = t.first_lon(lat_lon.lon); + double last_lon = t.last_lon(lat_lon.lon); + for (lon = first_lon; lon <= last_lon; lon += 360.0) { + AltosPointDouble pt = t.screen(lat, lon); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + + if (0 <= state && state < AltosUIMap.stateColors.length) + g.setColor(AltosUIMap.stateColors[state]); + else + g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]); + + g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); + g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); + g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); + + if (label != null) { + Rectangle2D bounds; + bounds = line_font.getStringBounds(label, g.getFontRenderContext()); + float x = (float) pt.x; + float y = (float) pt.y + (float) bounds.getHeight() / 2.0f; + + g.setFont(line_font); + g.setColor(Color.WHITE); + for (int dy = -2; dy <= 2; dy += 2) + for (int dx = -2; dx <= 2; dx += 2) + g.drawString(label, x + dx, y + dy); + if (0 <= state && state < AltosUIMap.stateColors.length) + g.setColor(AltosUIMap.stateColors[state]); + else + g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]); + g.drawString(label, x, y); + } + } + } - g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10); - g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40); - g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70); + MapMark(double lat, double lon, int state, String label) { + super(lat, lon, state, label); } MapMark(double lat, double lon, int state) { @@ -105,7 +135,7 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM } private boolean is_drag_event(MouseEvent e) { - return e.getModifiers() == InputEvent.BUTTON1_MASK; + return e.getModifiersEx() == InputEvent.BUTTON1_DOWN_MASK; } /* MouseMotionListener methods */ @@ -114,7 +144,61 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM map.touch_continue(e.getPoint().x, e.getPoint().y, is_drag_event(e)); } + String pos(double p, String pos, String neg) { + if (p == AltosLib.MISSING) + return ""; + String h = pos; + if (p < 0) { + h = neg; + p = -p; + } + int deg = (int) Math.floor(p); + double min = (p - Math.floor(p)) * 60.0; + return String.format("%s %4d° %9.6f'", h, deg, min); + } + + String height(double h, String label) { + if (h == AltosLib.MISSING) + return ""; + return String.format(" %s%s", + AltosConvert.height.show(6, h), + label); + } + + String speed(double s, String label) { + if (s == AltosLib.MISSING) + return ""; + return String.format(" %s%s", + AltosConvert.speed.show(6, s), + label); + } + public void mouseMoved(MouseEvent e) { + AltosMapPathPoint point = map.nearest(e.getPoint().x, e.getPoint().y); + + if (point != null) { + if (nearest_mark == null) + nearest_mark = map.add_mark(point.gps.lat, + point.gps.lon, + point.state); + else { + nearest_mark.lat_lon.lat = point.gps.lat; + nearest_mark.lat_lon.lon = point.gps.lon; + nearest_mark.state = point.state; + } + nearest_label.setText(String.format("%9.2f sec %s%s%s%s", + point.time, + pos(point.gps.lat, + "N", "S"), + pos(point.gps.lon, + "E", "W"), + height(point.gps_height, ""), + speed(point.gps.ground_speed, "(h)"), + speed(point.gps.climb_rate, "(v)"))); + } else { + nearest_label.setText(""); + } + repaint(); } /* MouseListener methods */ @@ -221,7 +305,7 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); for (AltosMapPathPoint point : points) { - Point2D.Double cur = point2d(t.screen(point.lat_lon)); + Point2D.Double cur = point2d(t.screen(point.gps.lat, point.gps.lon)); if (prev != null) { Line2D.Double line = new Line2D.Double (prev, cur); Rectangle bounds = line.getBounds(); @@ -263,6 +347,21 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM if (image != null) { g.drawImage(image, point.x, point.y, null); +/* + * Useful when debugging map fetching problems + * + String message = String.format("%.6f %.6f", center.lat, center.lon); + g.setFont(tile_font); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext()); + + float x = px_size / 2.0f; + float y = px_size / 2.0f; + x = x - (float) bounds.getWidth() / 2.0f; + y = y + (float) bounds.getHeight() / 2.0f; + g.setColor(Color.RED); + g.drawString(message, (float) point_double.x + x, (float) point_double.y + y); +*/ } else { g.setColor(Color.GRAY); g.fillRect(point.x, point.y, px_size, px_size); @@ -277,10 +376,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM message = "Internal error"; break; case AltosMapTile.failed: - message = "Network error, check connection"; + message = "Network error"; break; case AltosMapTile.forbidden: - message = "Too many requests, try later"; + message = "Outside of known launch areas"; break; } if (message != null && tile_font != null) { @@ -332,6 +431,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM return new MapMark(lat, lon, state); } + public AltosMapMark new_mark(double lat, double lon, int state, String label) { + return new MapMark(lat, lon, state, label); + } + public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) { return new MapTile(cache, upper_left, center, zoom, maptype, px_size, scale); } @@ -371,6 +474,8 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM public void set_font() { tile_font = AltosUILib.value_font; line_font = AltosUILib.status_font; + if (nearest_label != null) + nearest_label.setFont(AltosUILib.value_font); } public void font_size_changed(int font_size) { @@ -384,9 +489,13 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM JLabel zoom_label; + JLabel nearest_label; + public void set_maptype(int type) { +/* map.set_maptype(type); maptype_combo.setSelectedIndex(type); +*/ } /* AltosUIMapPreload functions */ @@ -399,6 +508,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM map.add_mark(lat, lon, status); } + public void add_mark(double lat, double lon, int status, String label) { + map.add_mark(lat, lon, status, label); + } + public void clear_marks() { map.clear_marks(); } @@ -412,6 +525,10 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM map.show(state, listener_state); } + public void show(AltosGPS gps, double time, int state, double gps_height) { + map.show(gps, time, state, gps_height); + } + public String getName() { return "Map"; } @@ -421,10 +538,16 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM map.centre(state); } + public void centre(AltosGPS gps) { + map.centre(gps); + } + /* internal layout bits */ private GridBagLayout layout = new GridBagLayout(); +/* JComboBox maptype_combo; +*/ MapView view; @@ -513,6 +636,21 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM c.weighty = 0; add(zoom_out, c); + + nearest_label = new JLabel("", JLabel.LEFT); + nearest_label.setFont(tile_font); + + c = new GridBagConstraints(); + c.anchor = GridBagConstraints.CENTER; + c.fill = GridBagConstraints.HORIZONTAL; + c.gridx = 0; + c.gridy = 11; + c.weightx = 0; + c.weighty = 0; + c.gridwidth = 1; + c.gridheight = 1; + add(nearest_label, c); +/* maptype_combo = new JComboBox(map.maptype_labels); maptype_combo.setEditable(false); @@ -531,7 +669,7 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM c.weightx = 0; c.weighty = 0; add(maptype_combo, c); - +*/ map = new AltosMap(this); } }