using System; using System.Collections.Generic; using System.Text; namespace bsmd.AIS2Service { public class AIS_Target { #region private members public static TimeSpan dbUpdateInterval = new TimeSpan(0, 2, 0); // neue Position in DB schreiben (min Interval) private int mmsi; private bool isClassB = false; private bool? isWatchkeeper = null; private DateTime? lastUpdate; private bool updateDB = false; private string name; private string station; private string lastDBName; private string callSign; private bool selected = false; private AISClass staticInfo; private AISClass posReport; private AISClass lastAdditionalData; private AIS_Target.Type type = Type.OTHER; private AIS_Target.NavStatus navStatus = AIS_Target.NavStatus.UNKNOWN; #endregion #region public defs public enum Type { PASSENGER, CARGO, TANKER, HSC, WIG, TUG, YACHT, OTHER } /// /// vereinfacht /// public enum NavStatus { UNKNOWN, UNDERWAY, MOORED } #endregion #region Construction public AIS_Target(int mmsi) { this.mmsi = mmsi; } #endregion #region Properties public int MMSI { get { return this.mmsi; } } public DateTime? LastUpdate { get { return this.lastUpdate; } } public string Name { get { if ((this.name == null) || (this.name.Length == 0)) return this.LastDBName; return this.name; } set { this.name = value; } } public string Callsign { get { return this.callSign; } set { this.callSign = value; } } public string LastDBName { get { return this.lastDBName; } set { this.lastDBName = value; } } public string ReceivedFrom { get { return this.station; } } internal AISClass LastPosReport { get { return this.posReport; } } internal AISClass LastStaticData { get { return this.staticInfo; } } public double? Latitude { get { if (this.LastPosReport == null) return null; if (this.LastPosReport is AIS_PosReport) return ((AIS_PosReport)this.LastPosReport).Latitude; if (this.LastPosReport is AIS_ClassB) return ((AIS_ClassB)this.LastPosReport).Latitude; if (this.LastPosReport is AIS_ClassBExt) return ((AIS_ClassBExt)this.LastPosReport).Latitude; return null; } } public Type TargetType { get { return this.type; } set { this.type = value; } } public NavStatus TargetNavStatus { get { return this.navStatus; } } public double? Longitude { get { if (this.LastPosReport == null) return null; if (this.LastPosReport is AIS_PosReport) return ((AIS_PosReport)this.LastPosReport).Longitude; if (this.LastPosReport is AIS_ClassB) return ((AIS_ClassB)this.LastPosReport).Longitude; if (this.LastPosReport is AIS_ClassBExt) return ((AIS_ClassBExt)this.LastPosReport).Longitude; return null; } } public bool? IsClassB { get { return this.isClassB; } } public int? Heading { get { if (this.LastPosReport == null) return null; if (this.LastPosReport is AIS_PosReport) return ((AIS_PosReport)this.LastPosReport).TrueHeading; if (this.LastPosReport is AIS_ClassB) return ((AIS_ClassB)this.LastPosReport).TrueHeading; if (this.LastPosReport is AIS_ClassBExt) return ((AIS_ClassBExt)this.LastPosReport).TrueHeading; return null; } } public int? COG { get { if (this.LastPosReport == null) return null; if (this.LastPosReport is AIS_PosReport) return (int)((AIS_PosReport)this.LastPosReport).COG; if (this.LastPosReport is AIS_ClassB) return (int)((AIS_ClassB)this.LastPosReport).Cog; if (this.LastPosReport is AIS_ClassBExt) return (int) ((AIS_ClassBExt)this.LastPosReport).Cog; return null; } } public bool? IsWatchkeeperShip { get { return this.isWatchkeeper; } set { this.isWatchkeeper = value; } } public bool Selected { get { return this.selected; } set { this.selected = value; } } public string Station { get { return this.station; } set { this.station = value; } } #endregion #region public methods public static AIS_Target.NavStatus GetCurrentNavstatus(int status) { AIS_Target.NavStatus result = NavStatus.UNKNOWN; switch (status) { case 0: case 8: result = NavStatus.UNDERWAY; break; default: result = NavStatus.MOORED; break; } return result; } internal void Update(AISClass message) { switch (message.MessageType) { case AISClass.AISType.POSITION_REPORT: case AISClass.AISType.POSITION_REPORT_ASSIGNED: case AISClass.AISType.POSITION_REPORT_SPECIAL: if ((this.lastUpdate.HasValue && (((AIS_PosReport)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) || (!this.lastUpdate.HasValue)) { this.updateDB = true; this.lastUpdate = ((AIS_PosReport)message).Timestamp; } this.posReport = message; this.navStatus = AIS_Target.GetCurrentNavstatus(((AIS_PosReport)message).NavStatusVal); // System.Diagnostics.Trace.WriteLine(string.Format("pos report at {0}", this.lastUpdate)); break; case AISClass.AISType.POSITION_REPORT_B_EQUIP: if ((this.lastUpdate.HasValue && (((AIS_ClassB)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) || (!this.lastUpdate.HasValue)) { this.updateDB = true; this.lastUpdate = ((AIS_ClassB)message).Timestamp; this.isClassB = true; this.type = Type.YACHT; this.navStatus = NavStatus.UNDERWAY; } this.posReport = message; break; case AISClass.AISType.POSITION_REPORT_B_EQUIP_EXT: if ((this.lastUpdate.HasValue && (((AIS_ClassBExt)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) || (!this.lastUpdate.HasValue)) { this.updateDB = true; this.lastUpdate = ((AIS_ClassBExt)message).Timestamp; this.isClassB = true; this.type = Type.YACHT; this.navStatus = NavStatus.UNDERWAY; } this.posReport = message; break; case AISClass.AISType.STATIC_VOYAGE_DATA: this.staticInfo = message; this.name = ((AIS_StaticData)message).Name; this.callSign = ((AIS_StaticData)message).Callsign; //this.type = AIS_StaticData.GetShipTypeSimple(((AIS_StaticData)message).ShipTypeVal); break; case AISClass.AISType.CLASS_B_STATIC_DATA: if (((AIS_ClassBStatic)message).IsPartA) { this.name = ((AIS_ClassBStatic)message).Name; } else { this.callSign = ((AIS_ClassBStatic)message).Callsign; } this.staticInfo = message; this.type = Type.YACHT; this.isClassB = true; break; default: this.lastAdditionalData = message; break; } } #endregion #region overrides public override string ToString() { return string.Format("{0} [{1}]", this.Name, this.MMSI); } #endregion } }