altosuilib: Show launch sites at all visible locations on map
authorKeith Packard <keithp@keithp.com>
Mon, 22 Mar 2021 06:10:25 +0000 (23:10 -0700)
committerKeith Packard <keithp@keithp.com>
Mon, 22 Mar 2021 06:10:25 +0000 (23:10 -0700)
Take each launch site and draw it at every location on the map it
occurs (in case the map shows more than the full globe). This also
automatically handles scrolling the map more than one "rotation".

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosMapTransform.java
altosuilib/AltosUIMap.java
altosuilib/AltosUIMapPreload.java

index ba9d1ae46121ca5ce72895562dd13ec736e88a38..3f8f290c9f87faa419358de317a3210ea879d583 100644 (file)
@@ -29,6 +29,8 @@ public class AltosMapTransform {
 
        double  offset_x, offset_y;
 
+       int     width, height;
+
        public AltosLatLon lat_lon (AltosPointDouble point) {
                double lat, lon;
                double rads;
@@ -110,6 +112,39 @@ public class AltosMapTransform {
                return screen(point(lat, lon));
        }
 
+       /* Return first longitude value which ends up on-screen */
+       public double first_lon(double lon) {
+               /* Find a longitude left of the screen */
+               for (;;) {
+                       double x = lon * scale_x - offset_x;
+                       if (x < 0)
+                               break;
+                       lon -= 360.0;
+               }
+               /* Find the first longitude on the screen */
+               for (;;) {
+                       double x = lon * scale_x - offset_x;
+                       if (x >= 0)
+                               break;
+                       lon += 360.0;
+               }
+               return lon;
+       }
+
+       /* Return last longitude value which ends up on-screen */
+       public double last_lon(double lon) {
+               lon = first_lon(lon);
+
+               for(;;) {
+                       double next_lon = lon + 360.0;
+                       double next_x = next_lon * scale_x - offset_x;
+                       if (next_x >= width)
+                               break;
+                       lon = next_lon;
+               }
+               return lon;
+       }
+
        private boolean has_location;
 
        public boolean has_location() {
@@ -120,6 +155,9 @@ public class AltosMapTransform {
                scale_x = 256/360.0 * Math.pow(2, zoom);
                scale_y = 256/(2.0*Math.PI) * Math.pow(2, zoom);
 
+               this.width = width;
+               this.height = height;
+
                AltosPointDouble centre_pt = point(centre_lat_lon);
 
                has_location = (centre_lat_lon.lat != 0 || centre_lat_lon.lon != 0);
index 58371f05a090d892f88bc4f74ade73763a00039b..0a80959fe80a9c02416968f8e35beed860f03f3e 100644 (file)
@@ -48,37 +48,43 @@ public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosM
 
        class MapMark extends AltosMapMark {
                public void paint(AltosMapTransform t) {
-                       AltosPointDouble pt = t.screen(lat_lon);
+                       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));
+                               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);
+
+                               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);
+                               }
                        }
                }
 
index 1fec169cd0e6e70ba0ad5b0c2e3f6f4d1a613225..6d0d8b70576e881cae6ec9473eccad5627acd424 100644 (file)
@@ -230,10 +230,6 @@ public class AltosUIMapPreload extends AltosUIFrame implements ActionListener, I
 
        void add_mark(double lat, double lon, int state, String label) {
                map.add_mark(lat, lon, state, label);
-               if (lon <= 0)
-                       map.add_mark(lat, lon + 360, state, label);
-               if (lon >= 0)
-                       map.add_mark(lat, lon - 360, state, label);
        }
 
        void reset_marks() {