public static PlanePosition DecodeGlobalADSB(ADSBPositionMessage OldADSBMessage, ADSBPositionMessage NewADSBMessage) { if (!OldADSBMessage.ICAO.Equals(NewADSBMessage.ICAO)) { throw new ArgumentException("Not the same ICAO! -> CPRCoder static PlanePosition"); } if (OldADSBMessage.CprFormate == NewADSBMessage.CprFormate) { throw new ArgumentException("Same CPR - Error!"); } TimeSpan OldMesTimespan = TimeSpan.FromTicks(OldADSBMessage.Timestamp.Ticks); TimeSpan NewMesTimespan = TimeSpan.FromTicks(NewADSBMessage.Timestamp.Ticks); if ((NewMesTimespan.TotalSeconds - OldMesTimespan.TotalSeconds) > 10) { throw new ArgumentException("Timestamp too old!"); } int i = NewADSBMessage.CprFormate; //Latitude double CprLat0 = (i == 0) ? NewADSBMessage.CprLatitude : OldADSBMessage.CprLatitude; double CprLat1 = (i == 1) ? NewADSBMessage.CprLatitude : OldADSBMessage.CprLatitude; double j = Math.Floor(((59 * CprLat0 - 60 * CprLat1) / Nb17) + 0.5); double RLat0 = Dlat0 * (mod(j, 60) + CprLat0 / Nb17); double RLat1 = Dlat1 * (mod(j, 59) + CprLat1 / Nb17); double latitude = (i == 0) ? RLat0 : RLat1; int nl = 0; if ((nl = NumberOfLongitudeZones.lookup(RLat0)) != NumberOfLongitudeZones.lookup(RLat1)) { // if the longitude zones are not the same, we cannot calculate the longitude // so we discard this position object throw new ArgumentException("CprCoder.decodeGlobalAirborne(): Messages with matching number of longitude zones expected"); } double CprLon0 = (i == 0) ? NewADSBMessage.CprLongitude : OldADSBMessage.CprLongitude; double CprLon1 = (i == 1) ? NewADSBMessage.CprLongitude : OldADSBMessage.CprLongitude; double m = Math.Floor((CprLon0 * (nl - 1) - CprLon1 * nl) / Nb17 + 0.5); double lon = (i == 0) ? CprLon0 : CprLon1; double dlon = 360.0 / Math.Max(nl - i, 1); double longitude = dlon * (mod(m, nl - i) + lon / Nb17); //System.err.println ( String.format("%-8s LAT LON %-3.8f %-3.8f global pos", newMsg.getIcao(), latitude, longitude) ); return(new PlanePosition(NewADSBMessage.Timestamp, (double)latitude, (double)longitude, (double)NewADSBMessage.Altitude)); }
public const double Nb17 = 131072.0; //Number of bits for Encoding public static PlanePosition DecodeADSBToPosition(PlanePosition ReferencePosition, ADSBPositionMessage NewMessage) { double LatitudeReference = ReferencePosition.Latitude; double LongitudeReference = ReferencePosition.Longitude; int LatitudeCpr = NewMessage.CprLatitude; int LongitudeCpr = NewMessage.CprLongitude; int Cpr = NewMessage.CprFormate; double DLat = (Cpr == 0) ? Dlat0 : Dlat1; double j = Math.Floor(LatitudeReference / DLat) + Math.Floor(0.5 + mod(LatitudeReference, DLat) / DLat - LatitudeCpr / Nb17); double RLat = (double)DLat * (j + LatitudeCpr / Nb17); double Dlon = 360.0 / (NumberOfLongitudeZones.lookup(RLat) - Cpr); double m = Math.Floor(LongitudeReference / Dlon) + Math.Floor(0.5 + mod(LongitudeReference, Dlon) / Dlon - LongitudeCpr / Nb17); double RLon = (double)Dlon * (m + LongitudeCpr / Nb17); return(new PlanePosition(NewMessage.Timestamp, (double)RLat, (double)RLon, (double)NewMessage.Altitude)); }