/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jadsb.data;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.render.GlobeAnnotation;
import gov.nasa.worldwind.render.Polyline;
import gov.nasa.worldwind.render.SurfaceIcon;
import jadsb.adsb.message.ADSBMessage;
import jadsb.adsb.message.ADSBMsg1;
import jadsb.adsb.message.ADSBMsg2;
import jadsb.adsb.message.ADSBMsg3;
import jadsb.adsb.message.ADSBMsg4;
import java.awt.Color;
import java.text.DecimalFormat;
import java.util.LinkedList;
import ui.layers.AircraftLayer;
import ui.layers.AircraftTextLayer;
/**
*
* @author Benjamin Jakobus
* @since 2.0
*/
public class Aircraft {
private enum LabelCycle {
ID, Callsign, Speed, Altitude, isOnGround
}
private LabelCycle currentLabelCycle = LabelCycle.ID;
/* Unique ID */
private String id = "unknown";
private String flightID = "unknown";
private String callSign = "unknown";
private boolean isOnGround = false;
private boolean emergencyFlag = false;
/* The targets movement trail. */
private LinkedList<Position> trail;
private Polyline visibleTrail;
/* The aircraft's last reported position. */
private Position currentPos;
private SurfaceIcon icon;
private PlaneModel planeModel;
private double track;
/* The aircraft's speed over ground. */
private String speed;
private GlobeAnnotation label;
public Aircraft(String id, String flightID) {
this.id = id;
this.flightID = flightID;
trail = new LinkedList<Position>();
visibleTrail = new Polyline(trail);
visibleTrail.setColor(Color.YELLOW);
visibleTrail.setLineWidth(2.0);
AircraftLayer.getInstance().addRenderable(visibleTrail);
}
public void updatePosition(final Position currentPos) {
if (this.currentPos == null) {
icon = new SurfaceIcon(getClass().getResource("/assets/icons/adsb/aircraft.png"), currentPos);
planeModel = new PlaneModel(100.0, 50.0, Color.YELLOW);
planeModel.setPosition(currentPos);
planeModel.setHeading(Angle.fromDegrees(track));
label = new GlobeAnnotation(callSign, currentPos);
Thread t = new Thread(new Runnable() {
public void run() {
DecimalFormat df = new DecimalFormat("#.##");
while (true) {
switch (currentLabelCycle) {
case ID:
label.setText(flightID);
currentLabelCycle = LabelCycle.Callsign;
break;
case Callsign:
label.setText(callSign);
currentLabelCycle = LabelCycle.Speed;
break;
case Speed:
label.setText(speed + " kts");
currentLabelCycle = LabelCycle.Altitude;
break;
case Altitude:
label.setText(df.format(currentPos.elevation) + " m");
currentLabelCycle = LabelCycle.isOnGround;
break;
case isOnGround:
label.setText((isOnGround ? "landed" : "in flight"));
currentLabelCycle = LabelCycle.ID;
break;
}
try {
Thread.sleep(5000);
} catch (Exception e) {
}
}
}
});
t.start();
AircraftLayer.getInstance().addRenderable(icon);
AircraftLayer.getInstance().addRenderable(planeModel);
AircraftTextLayer.getInstance().addAnnotation(label);
} else {
trail.add(this.currentPos);
visibleTrail.setPositions(trail);
icon.setLocation(currentPos);
label.setPosition(currentPos);
planeModel.setPosition(currentPos);
}
this.currentPos = currentPos;
}
public void updateTrack(double track) {
this.track = track;
if (planeModel != null) {
icon.setHeading(Angle.fromDegrees(track));
planeModel.setHeading(Angle.fromDegrees(track));
}
}
public void update(ADSBMessage msg) {
switch (msg.getType()) {
case 1:
ADSBMsg1 m1 = (ADSBMsg1) msg;
callSign = m1.getCallsign();
break;
case 2:
ADSBMsg2 m2 = (ADSBMsg2) msg;
updatePosition(new Position(LatLon.fromDegrees(m2.getPosition().getLatitude(),
m2.getPosition().getLongitude()), m2.getAltitudeInMeters()));
speed = m2.getSpeed();
isOnGround = m2.isOnGround();
updateTrack(m2.getTrack());
break;
case 3:
ADSBMsg3 m3 = (ADSBMsg3) msg;
updatePosition(new Position(LatLon.fromDegrees(m3.getPosition().getLatitude(),
m3.getPosition().getLongitude()), m3.getAltitudeInMeters()));
isOnGround = m3.isOnGround();
emergencyFlag = m3.hasSentEmergencyCode();
break;
case 4:
ADSBMsg4 m4 = (ADSBMsg4) msg;
speed = m4.getSpeed();
updateTrack(m4.getTrack());
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
}//new MilStd2525TacticalSymbol(symbolId, position)
}
}