From 4a7ae2831563622ebb4a1d893764afd0e0e0dfbe Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Sat, 19 Nov 2016 16:50:33 -0500 Subject: Add prediction --- run.sh | 2 + src/com/benburwell/planes/data/Aircraft.java | 8 ++++ .../benburwell/planes/gui/AircraftTableModel.java | 8 ++-- .../gui/aircraftmap/AircraftMapComponent.java | 5 +- .../benburwell/planes/gui/aircraftmap/Plane.java | 55 ++++++++++++++++++---- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/run.sh b/run.sh index 531d3ea..d2dabf0 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,7 @@ #!/bin/sh +export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8 + mkdir -p out/production/1090 javac -d out/production/1090 $(find src -name '*.java') cd out/production/1090 diff --git a/src/com/benburwell/planes/data/Aircraft.java b/src/com/benburwell/planes/data/Aircraft.java index e0ca449..66a7a46 100644 --- a/src/com/benburwell/planes/data/Aircraft.java +++ b/src/com/benburwell/planes/data/Aircraft.java @@ -17,6 +17,7 @@ public class Aircraft implements Comparable { private long packetCount = 0; private double track; private double groundSpeed; + private double verticalRate; public Aircraft(String hexIdent) { this.hexIdent = hexIdent; @@ -45,6 +46,9 @@ public class Aircraft implements Comparable { if (packet.getGroundSpeed() != null) { this.groundSpeed = packet.getGroundSpeed(); } + if (packet.getVerticalRate() != null) { + this.verticalRate = packet.getVerticalRate(); + } } public Position getCurrentPosition() { @@ -75,6 +79,10 @@ public class Aircraft implements Comparable { return this.groundSpeed; } + public double getVerticalRate() { + return this.verticalRate; + } + @Override public int compareTo(Aircraft that) { return this.getHexIdent().compareTo(that.getHexIdent()); diff --git a/src/com/benburwell/planes/gui/AircraftTableModel.java b/src/com/benburwell/planes/gui/AircraftTableModel.java index 2ee6742..3931893 100644 --- a/src/com/benburwell/planes/gui/AircraftTableModel.java +++ b/src/com/benburwell/planes/gui/AircraftTableModel.java @@ -15,7 +15,7 @@ import java.util.Collections; */ public class AircraftTableModel extends AbstractTableModel { private Map aircraftMap; - private String[] columnNames = { "Hex", "Callsign", "Squawk", "Latitude", "Longitude", "Altitude", "Track", "Ground Speed", "Packets" }; + private String[] columnNames = { "Hex", "Callsign", "Squawk", "Latitude", "Longitude", "Altitude", "Vertical Rate", "Track", "Ground Speed", "Packets" }; public AircraftTableModel(AircraftStore store) { this.aircraftMap = store.getAircraft(); @@ -66,10 +66,12 @@ public class AircraftTableModel extends AbstractTableModel { case 5: return aircraft.getCurrentPosition().getAltitude(); case 6: - return aircraft.getTrack(); + return aircraft.getVerticalRate(); case 7: - return aircraft.getGroundSpeed(); + return aircraft.getTrack(); case 8: + return aircraft.getGroundSpeed(); + case 9: return aircraft.getPacketCount(); } return ""; diff --git a/src/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java b/src/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java index 50ddb13..e490dae 100644 --- a/src/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java +++ b/src/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java @@ -85,10 +85,7 @@ public class AircraftMapComponent implements ViewComponent { @Override public void aircraftStoreChanged() { List planes = new ArrayList<>(); - store.getAircraft().values().forEach(aircraft -> { - String name = !aircraft.getCallsign().isEmpty() ? aircraft.getCallsign() : aircraft.getHexIdent(); - planes.add(new Plane(name, aircraft.getCurrentPosition(), aircraft.getTrack())); - }); + store.getAircraft().values().forEach(aircraft -> planes.add(new Plane(aircraft))); mapPanel.setPlanes(planes); mapPanel.validate(); mapPanel.repaint(); diff --git a/src/com/benburwell/planes/gui/aircraftmap/Plane.java b/src/com/benburwell/planes/gui/aircraftmap/Plane.java index 8575334..2f98bab 100644 --- a/src/com/benburwell/planes/gui/aircraftmap/Plane.java +++ b/src/com/benburwell/planes/gui/aircraftmap/Plane.java @@ -1,5 +1,6 @@ package com.benburwell.planes.gui.aircraftmap; +import com.benburwell.planes.data.Aircraft; import com.benburwell.planes.data.Position; import com.benburwell.planes.gui.GraphicsTheme; @@ -10,7 +11,7 @@ import java.awt.geom.AffineTransform; * Created by ben on 11/19/16. */ public class Plane extends GeoPoint implements Drawable { - public final int TRIANGLE_HEIGHT = 8; + public final int TRIANGLE_HEIGHT = 6; public final int TRIANGLE_WIDTH = 4; public final int TEXT_OFFSET_X = 10; public final int TEXT_OFFSET_Y = 15; @@ -18,15 +19,23 @@ public class Plane extends GeoPoint implements Drawable { public final int MAX_COLOR_HEIGHT = 50000; private String name; private double heading; + private double speed; + private double verticalRate; - public Plane(String name, Position position, double heading) { - this(name, position.getLatitude(), position.getLongitude(), position.getAltitude(), heading); + public Plane(Aircraft ac) { + this(ac.getCallsign(), ac.getCurrentPosition(), ac.getTrack(), ac.getGroundSpeed(), ac.getVerticalRate()); } - public Plane(String name, double latitude, double longitude, double altitude, double heading) { + public Plane(String name, Position position, double heading, double speed, double verticalRate) { + this(name, position.getLatitude(), position.getLongitude(), position.getAltitude(), heading, speed, verticalRate); + } + + public Plane(String name, double latitude, double longitude, double altitude, double heading, double speed, double verticalRate) { super(latitude, longitude, altitude); this.name = name; this.heading = heading; + this.speed = speed; + this.verticalRate = verticalRate; } public int getFlightLevel() { @@ -60,14 +69,38 @@ public class Plane extends GeoPoint implements Drawable { return Math.toRadians(this.heading); } - public void drawTriangle(Graphics2D ctx, int x, int y) { + public double getSpeed() { + return this.speed; + } + + public void drawTriangle(Graphics2D ctx, int x, int y, int predictionLength) { AffineTransform at = new AffineTransform(); - //at.setToRotation(this.getAngle(), x, y); at.setToRotation(this.getAngle(), x, y); ctx.setTransform(at); int[] xs = new int[]{ x - TRIANGLE_WIDTH, x, x + TRIANGLE_WIDTH, x - TRIANGLE_WIDTH }; int[] ys = new int[]{ y + TRIANGLE_HEIGHT, y - TRIANGLE_HEIGHT, y + TRIANGLE_HEIGHT, y + TRIANGLE_HEIGHT }; - ctx.drawPolyline(xs, ys, 4); + ctx.fillPolygon(xs, ys, 4); + ctx.drawLine(x, y, x, y - predictionLength); + } + + public String getVerticalRateIndicator() { + if (this.verticalRate > 0) { + return "\u2191"; // ↑ + } else if (this.verticalRate < 0) { + return "\u2193"; // ↓ + } + return ""; + } + + public String getDisplayName() { + if (this.name == null || this.name.isEmpty()) { + return "-----"; + } + return this.name; + } + + public int getPredictionLength(double pixelsPerNauticalMile) { + return (int) (this.speed / 60.0 * pixelsPerNauticalMile); } public void drawOn(Graphics g, AircraftMap map) { @@ -78,14 +111,16 @@ public class Plane extends GeoPoint implements Drawable { // draw the plane dot Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(this.getPlaneColor()); - this.drawTriangle(g2d, x, y); + int predictedTrack = this.getPredictionLength(map.getPixelsPerNauticalMile()); + this.drawTriangle(g2d, x, y, predictedTrack); g2d.dispose(); // draw the name of the plane g.setColor(GraphicsTheme.Colors.BASE_5); - g.drawString(this.name, x + TEXT_OFFSET_X, y + TEXT_OFFSET_Y); - g.drawString("" + this.getFlightLevel(), x + TEXT_OFFSET_X, y + TEXT_OFFSET_Y + g.getFontMetrics().getHeight()); + g.drawString(this.getDisplayName(), x + TEXT_OFFSET_X, y + TEXT_OFFSET_Y); + String infoString = String.format("%d%s %.1f", this.getFlightLevel(), this.getVerticalRateIndicator(), this.getSpeed()); + g.drawString(infoString, x + TEXT_OFFSET_X, y + TEXT_OFFSET_Y + g.getFontMetrics().getHeight()); } } } -- cgit v1.2.3