From c384ad0e18129b9cb95b6015233d315ae105743c Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Sun, 20 Nov 2016 04:25:52 -0500 Subject: Draw runways --- .../java/com/benburwell/planes/data/Runway.java | 161 +++++++++++++++++++++ .../com/benburwell/planes/gui/GraphicsTheme.java | 3 +- .../java/com/benburwell/planes/gui/Main1090.java | 9 +- .../planes/gui/aircraftmap/AircraftMap.java | 14 ++ .../gui/aircraftmap/AircraftMapComponent.java | 7 +- .../gui/aircraftmap/symbols/RunwaySymbol.java | 62 ++++++++ 6 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/benburwell/planes/data/Runway.java create mode 100644 src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/RunwaySymbol.java (limited to 'src/main/java') diff --git a/src/main/java/com/benburwell/planes/data/Runway.java b/src/main/java/com/benburwell/planes/data/Runway.java new file mode 100644 index 0000000..ad57833 --- /dev/null +++ b/src/main/java/com/benburwell/planes/data/Runway.java @@ -0,0 +1,161 @@ +package com.benburwell.planes.data; + +import org.apache.commons.csv.CSVRecord; + +/** + * @author ben + */ +public class Runway extends AbstractCSVReader { + private int id; + private int airportId; + private String airportIdent; + private Integer length; + private Integer width; + private String surface; + private boolean lighted; + private boolean closed; + private String leIdent; + private Double leLatitude; + private Double leLongitude; + private Double leElevation; + private Double leHeading; + private Integer leDisplacedThreshold; + private String heIdent; + private Double heLatitude; + private Double heLongitude; + private Double heElevation; + private Double heHeading; + private Integer heDisplacedThreshold; + + @Override + public void readRecord(CSVRecord record) { + this.id = Integer.valueOf(record.get("id")); + this.airportId = Integer.valueOf(record.get("airport_ref")); + this.airportIdent = record.get("airport_ident"); + try { + this.length = Integer.valueOf(record.get("length_ft")); + } catch (NumberFormatException e) {} + try { + this.width = Integer.valueOf(record.get("width_ft")); + } catch (NumberFormatException e) {} + this.surface = record.get("surface"); + this.lighted = record.get("lighted").equals("1"); + this.closed = record.get("closed").equals("1"); + this.leIdent = record.get("le_ident"); + try { + this.leLatitude = Double.valueOf(record.get("le_latitude_deg")); + } catch (NumberFormatException e) {} + try { + this.leLongitude = Double.valueOf(record.get("le_longitude_deg")); + } catch (NumberFormatException e) {} + try { + this.leElevation = Double.valueOf(record.get("le_elevation_ft")); + } catch (NumberFormatException e) {} + try { + this.leHeading = Double.valueOf(record.get("le_heading_degT")); + } catch (NumberFormatException e) {} + try { + this.leDisplacedThreshold = Integer.valueOf(record.get("le_displaced_threshold_ft")); + } catch (NumberFormatException e) {} + this.heIdent = record.get("he_ident"); + try { + this.heLatitude = Double.valueOf(record.get("he_latitude_deg")); + } catch (NumberFormatException e) {} + try { + this.heLongitude = Double.valueOf(record.get("he_longitude_deg")); + } catch (NumberFormatException e) {} + try { + this.heElevation = Double.valueOf(record.get("he_elevation_ft")); + } catch (NumberFormatException e) {} + try { + this.heHeading = Double.valueOf(record.get("he_heading_degT")); + } catch (NumberFormatException e) {} + try { + this.heDisplacedThreshold = Integer.valueOf(record.get("he_displaced_threshold_ft")); + } catch (NumberFormatException e) {} + } + + public boolean isDrawable() { + return !this.isClosed() && (this.getLeLatitude() != null) && (this.getLeLongitude() != null) && (this.getHeLatitude() != null) && (this.getHeLongitude() != null); + } + + public int getId() { + return id; + } + + public int getAirportId() { + return airportId; + } + + public String getAirportIdent() { + return airportIdent; + } + + public Integer getLength() { + return length; + } + + public Integer getWidth() { + return width; + } + + public String getSurface() { + return surface; + } + + public boolean isLighted() { + return lighted; + } + + public boolean isClosed() { + return closed; + } + + public String getLeIdent() { + return leIdent; + } + + public Double getLeLatitude() { + return leLatitude; + } + + public Double getLeLongitude() { + return leLongitude; + } + + public Double getLeElevation() { + return leElevation; + } + + public Double getLeHeading() { + return leHeading; + } + + public Integer getLeDisplacedThreshold() { + return leDisplacedThreshold; + } + + public String getHeIdent() { + return heIdent; + } + + public Double getHeLatitude() { + return heLatitude; + } + + public Double getHeLongitude() { + return heLongitude; + } + + public Double getHeElevation() { + return heElevation; + } + + public Double getHeHeading() { + return heHeading; + } + + public Integer getHeDisplacedThreshold() { + return heDisplacedThreshold; + } +} diff --git a/src/main/java/com/benburwell/planes/gui/GraphicsTheme.java b/src/main/java/com/benburwell/planes/gui/GraphicsTheme.java index f4a6525..7e28f57 100644 --- a/src/main/java/com/benburwell/planes/gui/GraphicsTheme.java +++ b/src/main/java/com/benburwell/planes/gui/GraphicsTheme.java @@ -31,9 +31,10 @@ public class GraphicsTheme { public static final Color MAP_NAVAID_COLOR = Colors.VIOLET; public static final Color MAP_AIRPORT_COLOR = Colors.MAGENTA; public static final Color MAP_ROUTE_COLOR = Colors.BASE_2; - public static final Color MAP_LABEL_COLOR = Colors.BLUE; + public static final Color MAP_LABEL_COLOR = Colors.CYAN; public static final Color MAP_PLANE_MIN_COLOR = Colors.RED; public static final Color MAP_PLANE_MAX_COLOR = Colors.GREEN; public static final Color MAP_PLANE_TRACK_COLOR = Colors.BASE_4; + public static final Color MAP_RUNWAY_BORDER_COLOR = Colors.BLUE; } } diff --git a/src/main/java/com/benburwell/planes/gui/Main1090.java b/src/main/java/com/benburwell/planes/gui/Main1090.java index ac75d03..71105a9 100644 --- a/src/main/java/com/benburwell/planes/gui/Main1090.java +++ b/src/main/java/com/benburwell/planes/gui/Main1090.java @@ -29,6 +29,7 @@ public class Main1090 extends JFrame { private AircraftStore aircraft = new AircraftStore(); private CSVObjectStore navaids = new CSVObjectStore<>(); private CSVObjectStore airports = new CSVObjectStore<>(); + private CSVObjectStore runways = new CSVObjectStore<>(); private RouteGraph routeGraph = new RouteGraph(); private int currentTcpConnection = 0; private JTabbedPane tabbedPane = new JTabbedPane(); @@ -59,6 +60,12 @@ public class Main1090 extends JFrame { System.out.println("Could not read airport file: " + e.getMessage()); } + try { + this.runways.readFromResource("/runways.csv", Runway.class); + } catch (IOException | InstantiationException | IllegalAccessException e) { + System.out.println("Could not read runway file: " + e.getMessage()); + } + try { CSVObjectStore intersections = new CSVObjectStore<>(); intersections.readFromResource("/airways_db.csv", Intersection.class); @@ -72,7 +79,7 @@ public class Main1090 extends JFrame { private void createTabs() { List tabs = new ArrayList<>(); - tabs.add(new AircraftMapComponent(this.aircraft, this.navaids, this.airports, this.routeGraph)); + tabs.add(new AircraftMapComponent(this.aircraft, this.navaids, this.airports, this.routeGraph, this.runways)); tabs.add(new AircraftTableComponent(this.aircraft)); tabs.add(new NavigationAidComponent(this.navaids)); tabs.add(new AirportsComponent(this.airports)); diff --git a/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMap.java b/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMap.java index 1e6181b..d98dc60 100644 --- a/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMap.java +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMap.java @@ -3,6 +3,7 @@ package com.benburwell.planes.gui.aircraftmap; import com.benburwell.planes.data.Airport; import com.benburwell.planes.data.NavigationAid; import com.benburwell.planes.data.Position; +import com.benburwell.planes.data.Runway; import com.benburwell.planes.graph.RouteGraph; import com.benburwell.planes.gui.GraphicsTheme; import com.benburwell.planes.gui.aircraftmap.symbols.*; @@ -51,6 +52,7 @@ public class AircraftMap extends JPanel { private List navaids = new ArrayList<>(); private List airports = new ArrayList<>(); private List routes = new ArrayList<>(); + private List runways = new ArrayList<>(); private double centerLatitude; private double centerLongitude; private int pixelsPerNauticalMile = 10; @@ -58,6 +60,7 @@ public class AircraftMap extends JPanel { private DisplayMode navaidDisplayMode = DisplayMode.HIDDEN; private DisplayMode airportDisplayMode = DisplayMode.HIDDEN; private DisplayMode routeDisplayMode = DisplayMode.HIDDEN; + private DisplayMode runwayDisplayMode = DisplayMode.HIDDEN; /** * Construct a map @@ -114,6 +117,10 @@ public class AircraftMap extends JPanel { routes.getAirways().forEach(airway -> this.routes.add(new RouteSymbol(airway))); } + public void addRunways(List runways) { + runways.forEach(runway -> this.runways.add(new RunwaySymbol(runway))); + } + /** * Paint the Tabbable on a Graphics instance * @@ -132,6 +139,8 @@ public class AircraftMap extends JPanel { this.drawPositionAndScale(g2d); this.drawRange(g2d); + this.runways.forEach(runway -> runway.drawOn(g2d, this, this.runwayDisplayMode)); + // Aids to Navigation this.navaids.forEach(aid -> aid.drawOn(g2d, this, this.navaidDisplayMode)); @@ -159,6 +168,11 @@ public class AircraftMap extends JPanel { this.redraw(); } + public void toggleRunways() { + this.runwayDisplayMode = this.runwayDisplayMode.next(); + this.redraw(); + } + private void drawPositionAndScale(Graphics g) { Font currentFont = g.getFont(); Font newFont = currentFont.deriveFont(FONT_SIZE); diff --git a/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java b/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java index 0899543..733a948 100644 --- a/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java @@ -12,6 +12,7 @@ import java.util.List; import javax.swing.JComponent; import javax.swing.Timer; import java.awt.event.KeyEvent; +import java.util.stream.Collectors; /** * @author ben @@ -24,7 +25,7 @@ public class AircraftMapComponent implements Tabbable { private AircraftMap mapPanel; private AircraftStoreListener aircraftStoreListener; - public AircraftMapComponent(AircraftStore store, CSVObjectStore navaids, CSVObjectStore airportStore, RouteGraph routeGraph) { + public AircraftMapComponent(AircraftStore store, CSVObjectStore navaids, CSVObjectStore airportStore, RouteGraph routeGraph, CSVObjectStore runwayStore) { this.store = store; this.setupMap(); @@ -35,6 +36,7 @@ public class AircraftMapComponent implements Tabbable { this.mapPanel.addNavAids(navaids.getObjects()); this.mapPanel.addAirports(airportStore.getObjects()); this.mapPanel.addRoutes(routeGraph); + this.mapPanel.addRunways(runwayStore.getObjects().stream().filter(Runway::isDrawable).collect(Collectors.toList())); final Timer t = new Timer(MAX_REFRESH_MILLIS, e -> { AircraftMapComponent.this.aircraftStoreListener.aircraftStoreChanged(); @@ -63,6 +65,7 @@ public class AircraftMapComponent implements Tabbable { * n toggle navaids * v toggle routes * f toggle airfields + * r toggle runways */ private void bindKeys() { KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(e -> { @@ -86,6 +89,8 @@ public class AircraftMapComponent implements Tabbable { this.mapPanel.toggleAirports(); } else if (e.getKeyCode() == KeyEvent.VK_V && e.getID() == KeyEvent.KEY_PRESSED) { this.mapPanel.toggleRoutes(); + } else if (e.getKeyCode() == KeyEvent.VK_R && e.getID() == KeyEvent.KEY_PRESSED) { + this.mapPanel.toggleRunways(); } return false; }); diff --git a/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/RunwaySymbol.java b/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/RunwaySymbol.java new file mode 100644 index 0000000..0f5fac1 --- /dev/null +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/RunwaySymbol.java @@ -0,0 +1,62 @@ +package com.benburwell.planes.gui.aircraftmap.symbols; + +import com.benburwell.planes.data.Runway; +import com.benburwell.planes.gui.GraphicsTheme; +import com.benburwell.planes.gui.aircraftmap.AircraftMap; +import com.benburwell.planes.gui.aircraftmap.DisplayMode; +import com.benburwell.planes.gui.aircraftmap.Drawable; +import com.benburwell.planes.gui.aircraftmap.GeoPoint; + +import java.awt.*; +import java.awt.geom.AffineTransform; + +/** + * @author ben + */ +public class RunwaySymbol implements Drawable { + public final double FEET_PER_MILE = 6076.12; + private Runway runway; + + public RunwaySymbol(Runway r) { + this.runway = r; + } + + @Override + public void drawOn(Graphics g, AircraftMap map, DisplayMode displayMode) { + if (!displayMode.equals(DisplayMode.HIDDEN)) { + GeoPoint he = new GeoPoint(this.runway.getHeLatitude(), this.runway.getHeLongitude(), 0); + int hex = he.getX(map); + int hey = he.getY(map); + + GeoPoint le = new GeoPoint(this.runway.getLeLatitude(), this.runway.getLeLongitude(), 0); + int lex = le.getX(map); + int ley = le.getY(map); + + if (he.shouldDrawOn(map) && le.shouldDrawOn(map)) { + //if (this.runway.getWidth() != null && this.runway.getLength() != null) { + // double dx = hex - lex; + // double dy = hey - ley; + // int width = (int) ((this.runway.getWidth() / FEET_PER_MILE) * map.getPixelsPerNauticalMile()); + // int length = (int) ((this.runway.getLength() / FEET_PER_MILE) * map.getPixelsPerNauticalMile()); + + // AffineTransform at = new AffineTransform(); + // at.setToRotation(Math.atan(dy / dx), lex, ley); + // Graphics2D g2d = (Graphics2D) g.create(); + // g2d.setColor(GraphicsTheme.Styles.MAP_RUNWAY_BORDER_COLOR); + // g2d.setTransform(at); + + // g2d.drawRect(lex - (width / 2), ley - (length / 2), width, length); + // g2d.dispose(); + //} + + g.setColor(GraphicsTheme.Styles.MAP_RUNWAY_BORDER_COLOR); + g.drawLine(lex, ley, hex, hey); + + if (displayMode.equals(DisplayMode.DETAILED)) { + g.drawString(runway.getLeIdent(), lex, ley); + g.drawString(runway.getHeIdent(), hex, hey); + } + } + } + } +} -- cgit v1.2.3