From 1d29a584c8387798fb1558fd54a09b1d8fbe90b7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 21 Mar 2021 23:10:25 -0700 Subject: [PATCH] altosuilib: Show launch sites at all visible locations on map 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 --- altoslib/AltosMapTransform.java | 38 +++++++++++++++++++++ altosuilib/AltosUIMap.java | 56 +++++++++++++++++-------------- altosuilib/AltosUIMapPreload.java | 4 --- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/altoslib/AltosMapTransform.java b/altoslib/AltosMapTransform.java index ba9d1ae4..3f8f290c 100644 --- a/altoslib/AltosMapTransform.java +++ b/altoslib/AltosMapTransform.java @@ -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); diff --git a/altosuilib/AltosUIMap.java b/altosuilib/AltosUIMap.java index 58371f05..0a80959f 100644 --- a/altosuilib/AltosUIMap.java +++ b/altosuilib/AltosUIMap.java @@ -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); + } } } diff --git a/altosuilib/AltosUIMapPreload.java b/altosuilib/AltosUIMapPreload.java index 1fec169c..6d0d8b70 100644 --- a/altosuilib/AltosUIMapPreload.java +++ b/altosuilib/AltosUIMapPreload.java @@ -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() { -- 2.30.2