From be4974518d4e24f66c19ceffc1e633e3e306956b Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Sun, 20 Nov 2016 01:14:47 -0500 Subject: Show track and remove planes after interval --- .../java/com/benburwell/planes/data/Aircraft.java | 26 ++++++++-- .../gui/aircraftmap/AircraftMapComponent.java | 59 +++++++++------------- .../planes/gui/aircraftmap/GeoPoint.java | 8 +++ .../gui/aircraftmap/symbols/PlaneSymbol.java | 34 ++++++++----- 4 files changed, 77 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/benburwell/planes/data/Aircraft.java b/src/main/java/com/benburwell/planes/data/Aircraft.java index 66a7a46..9f6b881 100644 --- a/src/main/java/com/benburwell/planes/data/Aircraft.java +++ b/src/main/java/com/benburwell/planes/data/Aircraft.java @@ -2,6 +2,7 @@ package com.benburwell.planes.data; import com.benburwell.planes.sbs.SBSPacket; +import java.util.Date; import java.util.List; import java.util.ArrayList; @@ -25,14 +26,24 @@ public class Aircraft implements Comparable { public void handleUpdate(SBSPacket packet) { this.packetCount++; + + Position newPosition = new Position(); + newPosition.setAltitude(this.currentPosition.getAltitude()); + newPosition.setLatitude(this.currentPosition.getLatitude()); + newPosition.setLongitude(this.currentPosition.getLongitude()); + newPosition.setTimestamp(this.currentPosition.getTimestamp()); + if (packet.getAltitude() != null) { - this.currentPosition.setAltitude(packet.getAltitude()); + newPosition.setAltitude(packet.getAltitude()); + newPosition.setTimestamp(new Date(System.currentTimeMillis())); } if (packet.getLatitude() != null) { - this.currentPosition.setLatitude(packet.getLatitude()); + newPosition.setLatitude(packet.getLatitude()); + newPosition.setTimestamp(new Date(System.currentTimeMillis())); } if (packet.getLongitude() != null) { - this.currentPosition.setLongitude(packet.getLongitude()); + newPosition.setLongitude(packet.getLongitude()); + newPosition.setTimestamp(new Date(System.currentTimeMillis())); } if (packet.getCallsign() != null && !packet.getCallsign().isEmpty()) { this.callsign = packet.getCallsign(); @@ -49,6 +60,11 @@ public class Aircraft implements Comparable { if (packet.getVerticalRate() != null) { this.verticalRate = packet.getVerticalRate(); } + + if (newPosition.getTimestamp().after(this.currentPosition.getTimestamp())) { + this.positionHistory.add(currentPosition); + this.currentPosition = newPosition; + } } public Position getCurrentPosition() { @@ -83,6 +99,10 @@ public class Aircraft implements Comparable { return this.verticalRate; } + public List getPositionHistory() { + return positionHistory; + } + @Override public int compareTo(Aircraft that) { return this.getHexIdent().compareTo(that.getHexIdent()); 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 305df99..ab0315d 100644 --- a/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/AircraftMapComponent.java @@ -4,21 +4,27 @@ import com.benburwell.planes.data.*; import com.benburwell.planes.gui.Tabbable; import com.benburwell.planes.gui.aircraftmap.symbols.PlaneSymbol; +import java.util.*; +import java.util.List; import javax.swing.*; +import javax.swing.Timer; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.util.List; -import java.util.ArrayList; /** * Created by ben on 11/18/16. */ public class AircraftMapComponent implements Tabbable { + public final long PLANE_EXPIRY_MILLIS = 60 * 1000; + public final int MAX_REFRESH_MILLIS = 5 * 1000; + private AircraftStore store; private CSVObjectStore navaids; private CSVObjectStore airportStore; private AircraftMap mapPanel; - private String focusedAircraftIdentifier = null; + private AircraftStoreListener aircraftStoreListener; public AircraftMapComponent(AircraftStore store, CSVObjectStore navaids, CSVObjectStore airportStore) { this.store = store; @@ -27,26 +33,16 @@ public class AircraftMapComponent implements Tabbable { this.setupMap(); this.bindKeys(); - this.subscribeToChanges(); + this.setupListener(); + + this.store.subscribe(this.aircraftStoreListener); this.mapPanel.addNavAids(this.navaids.getObjects()); this.mapPanel.addAirports(this.airportStore.getObjects()); - } - public void focusNextAircraft() { - // List aircraftIdentifiers = new ArrayList<>(this.store.getAircraft().keySet()); - // Collections.sort(aircraftIdentifiers); - // if (this.focusedAircraftIdentifier == null && aircraftIdentifiers.size() > 0) { - // this.focusedAircraftIdentifier = aircraftIdentifiers.get(0); - // } else { - // int idx = aircraftIdentifiers.indexOf(this.focusedAircraftIdentifier); - // if (idx > 0 && idx < aircraftIdentifiers.size() - 1) { - // this.focusedAircraftIdentifier = aircraftIdentifiers.get(idx++); - // } else if (aircraftIdentifiers.size() > 0) { - // this.focusedAircraftIdentifier = aircraftIdentifiers.get(0); - // } else { - // this.focusedAircraftIdentifier = null; - // } - // } + final Timer t = new Timer(MAX_REFRESH_MILLIS, e -> { + AircraftMapComponent.this.aircraftStoreListener.aircraftStoreChanged(); + }); + t.start(); } private void setupMap() { @@ -70,9 +66,6 @@ public class AircraftMapComponent implements Tabbable { this.mapPanel.moveNorth(); } else if (e.getKeyCode() == KeyEvent.VK_0 && e.getID() == KeyEvent.KEY_PRESSED) { this.mapPanel.setCenter(40.6188942, -75.4947205); - } else if (e.getKeyCode() == KeyEvent.VK_TAB && e.getID() == KeyEvent.KEY_PRESSED) { - this.focusNextAircraft(); - this.centerMapOnPlane(this.focusedAircraftIdentifier); } else if (e.getKeyCode() == KeyEvent.VK_N && e.getID() == KeyEvent.KEY_PRESSED) { this.mapPanel.toggleNavAids(); } else if (e.getKeyCode() == KeyEvent.VK_A && e.getID() == KeyEvent.KEY_PRESSED) { @@ -82,19 +75,17 @@ public class AircraftMapComponent implements Tabbable { }); } - private void centerMapOnPlane(String identifier) { - if (identifier != null) { - Position pos = this.store.getAircraft().get(identifier).getCurrentPosition(); - this.mapPanel.setCenter(pos.getLatitude(), pos.getLongitude()); - } - } - - private void subscribeToChanges() { - this.store.subscribe(new AircraftStoreListener() { + private void setupListener() { + this.aircraftStoreListener = new AircraftStoreListener() { @Override public void aircraftStoreChanged() { + Date minTime = new Date(System.currentTimeMillis() - PLANE_EXPIRY_MILLIS); List planes = new ArrayList<>(); - store.getAircraft().values().forEach(aircraft -> planes.add(new PlaneSymbol(aircraft))); + store.getAircraft().values().forEach(aircraft -> { + if (aircraft.getCurrentPosition().getTimestamp().after(minTime)) { + planes.add(new PlaneSymbol(aircraft)); + } + }); mapPanel.setPlanes(planes); mapPanel.validate(); mapPanel.repaint(); @@ -104,7 +95,7 @@ public class AircraftMapComponent implements Tabbable { public boolean respondTo(String aircraftId) { return true; } - }); + }; } @Override diff --git a/src/main/java/com/benburwell/planes/gui/aircraftmap/GeoPoint.java b/src/main/java/com/benburwell/planes/gui/aircraftmap/GeoPoint.java index 80c6204..2ecbeda 100644 --- a/src/main/java/com/benburwell/planes/gui/aircraftmap/GeoPoint.java +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/GeoPoint.java @@ -1,5 +1,7 @@ package com.benburwell.planes.gui.aircraftmap; +import com.benburwell.planes.data.Position; + /** * Created by ben on 11/19/16. */ @@ -8,6 +10,12 @@ public class GeoPoint { private double longitude; private double altitude; + public GeoPoint(Position position) { + this.latitude = position.getLatitude(); + this.longitude = position.getLongitude(); + this.altitude = position.getAltitude(); + } + public GeoPoint(double latitude, double longitude, double altitude) { this.latitude = latitude; this.longitude = longitude; diff --git a/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/PlaneSymbol.java b/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/PlaneSymbol.java index 4e8ebc0..135ed4d 100644 --- a/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/PlaneSymbol.java +++ b/src/main/java/com/benburwell/planes/gui/aircraftmap/symbols/PlaneSymbol.java @@ -7,6 +7,9 @@ import com.benburwell.planes.gui.aircraftmap.AircraftMap; import com.benburwell.planes.gui.aircraftmap.Drawable; import com.benburwell.planes.gui.aircraftmap.GeoPoint; +import java.util.Date; +import java.util.List; +import java.util.ArrayList; import java.awt.*; import java.awt.geom.AffineTransform; @@ -20,25 +23,24 @@ public class PlaneSymbol extends GeoPoint implements Drawable { public final int TEXT_OFFSET_Y = 15; public final int MIN_COLOR_HEIGHT = 0; public final int MAX_COLOR_HEIGHT = 50000; + public final long HISTORY_MILLIS = 5 * 60 * 1000; private String name; private double heading; private double speed; private double verticalRate; + private List historyTrack = new ArrayList<>(); public PlaneSymbol(Aircraft ac) { - this(ac.getCallsign(), ac.getCurrentPosition(), ac.getTrack(), ac.getGroundSpeed(), ac.getVerticalRate()); - } - - public PlaneSymbol(String name, Position position, double heading, double speed, double verticalRate) { - this(name, position.getLatitude(), position.getLongitude(), position.getAltitude(), heading, speed, verticalRate); - } - - public PlaneSymbol(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; + super(ac.getCurrentPosition()); + this.name = ac.getCallsign(); + this.heading = ac.getTrack(); + this.speed = ac.getGroundSpeed(); + this.verticalRate = ac.getVerticalRate(); + + Date minTime = new Date(System.currentTimeMillis() - HISTORY_MILLIS); + ac.getPositionHistory().stream() + .filter(pos -> pos.getTimestamp().after(minTime)) + .forEach(pos -> historyTrack.add(pos)); } public int getFlightLevel() { @@ -118,6 +120,12 @@ public class PlaneSymbol extends GeoPoint implements Drawable { this.drawTriangle(g2d, x, y, predictedTrack); g2d.dispose(); + // draw the history track + g.setColor(GraphicsTheme.Colors.BASE_4); + this.historyTrack.forEach(pos -> { + GeoPoint p = new GeoPoint(pos); + g.fillRect(p.getX(map) - 2, p.getY(map) - 2, 4, 4); + }); // draw the name of the plane g.setColor(GraphicsTheme.Colors.BASE_5); -- cgit v1.2.3