コード例 #1
0
        /// <summary>
        /// Processing a grounded flight
        /// We can adjust its position and look for takeoffs
        /// </summary>
        private void ProcessGrounded(AdsbEvent currentEvent)
        {
            //Set the last auport first if it hasn been set yet
            // This happens if we enter GROUNDED from Unknown
            if (LastAirport == null && LastKnownPosition != null)
            {
                LastAirport = Airports.GetClosestAirport(LastKnownPosition);
            }

            // This is where we can process flights as they slow down. We can assume a reasonable distance here
            // The goal is to get coser and closer with the airport until we hit taxi speed
            // Inspired by A44D3F Delta - and the multitude of CLos Angeles area municipal airports
            if (LastGroundedFlight != null)
            {
                if (currentEvent.Speed != null && currentEvent.Speed > REASONABLE_TAXI_SPEED)
                {
                    Airport tempAirport = Airports.GetClosestAirport(LastKnownPosition);
                    if (tempAirport.Identifier != LastAirport.Identifier)
                    {
                        UpdateLastGroundedFlight(tempAirport);
                    }
                }
            }

            //The goal here is to look for takeoffs
            // This means we have a Reasonable grounding delay of 15 minutes before searching for takeoff speed
            bool takeoffEligible = true;

            if (LastGrounded != null)
            {
                // we will ignore events to let the plane land
                TimeSpan landSpan    = currentEvent.Timestamp.Subtract((DateTime)LastGrounded);
                double   landSeconds = landSpan.TotalSeconds;
                if (landSeconds < REASONABLE_GROUNDING_DELAY)
                {
                    takeoffEligible = false;
                }
            }
            if ((currentEvent.Speed) != null && takeoffEligible)
            {
                LastDeviceSpeed     = currentEvent.Speed;
                LastDeviceSpeedTime = currentEvent.Timestamp;

                // We have hit takeoff speed, change status
                if (currentEvent.Speed > AirplaneProcessed.Model.TakeoffSpeed)
                {
                    // We are taking off
                    //Console.WriteLine("Taking off at " + currentEvent.Timestamp);
                    CurrentStatus = AirplaneStatus.FLYING;
                    LastTakeoff   = currentEvent.Timestamp;
                }
            }
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: northos/CodingExercise
        private static FlightCollection CalculateFlights(AirportCollection airports, AdsbEventCollection events)
        {
            // Organize all ADS-B events by aircraft ID
            FlightCollection flights = new FlightCollection();
            Dictionary <string, List <AdsbEvent> > eventsByID = new Dictionary <string, List <AdsbEvent> >();

            foreach (AdsbEvent adsbEvent in events.Events)
            {
                if (!eventsByID.ContainsKey(adsbEvent.Identifier))
                {
                    eventsByID.Add(adsbEvent.Identifier, new List <AdsbEvent>());
                    eventsByID[adsbEvent.Identifier].Add(adsbEvent);
                }
                else
                {
                    // Remove events that are soon after the previous one to improve performance
                    int       eventCount = eventsByID[adsbEvent.Identifier].Count;
                    AdsbEvent lastEvent  = eventsByID[adsbEvent.Identifier][eventCount - 1];
                    TimeSpan  timeDiff   = adsbEvent.Timestamp - lastEvent.Timestamp;
                    if (timeDiff.TotalSeconds >= TimeThreshold)
                    {
                        eventsByID[adsbEvent.Identifier].Add(adsbEvent);
                    }
                }
            }

            // For each aircraft identifier, step through the logged events in sequence to identify flights
            foreach (string identifier in eventsByID.Keys)
            {
                List <AdsbEvent> eventLog       = eventsByID[identifier];
                FlightStatus     flightStatus   = FlightStatus.Unknown;
                Airport          lastAirport    = new Airport();
                DateTime         lastGroundTime = DateTime.MinValue;
                foreach (AdsbEvent adsbEvent in eventLog)
                {
                    // Find closest airport to the logged coordinates, as long as the event has coordinate values
                    GeoCoordinate eventLoc = new GeoCoordinate(adsbEvent.Latitude ?? double.NaN, adsbEvent.Longitude ?? double.NaN);
                    if (eventLoc.HasLocation())
                    {
                        Airport       closestAirport  = airports.GetClosestAirport(eventLoc);
                        GeoCoordinate airportLoc      = new GeoCoordinate(closestAirport.Latitude, closestAirport.Longitude);
                        double        airportDistance = eventLoc.GetDistanceTo(airportLoc);
                        double        altitudeDiff    = adsbEvent.Altitude.HasValue ? Math.Abs(adsbEvent.Altitude.Value - closestAirport.Elevation) : 0f;
                        double        speed           = adsbEvent.Speed ?? 0f;

                        // If the event was logged close to an airport, assume the aircraft has landed at that airport
                        if (airportDistance <= DistanceThreshold && altitudeDiff <= AltitudeThreshold && speed <= SpeedThreshold)
                        {
                            // If this is not the first event (status unknown) and the new closest airport is different, create a new completed flight record
                            if (flightStatus != FlightStatus.Unknown && closestAirport.Identifier != lastAirport.Identifier)
                            {
                                flights.Flights.Add(new Flight
                                {
                                    AircraftIdentifier = identifier,
                                    DepartureTime      = lastGroundTime,
                                    DepartureAirport   = lastAirport.Identifier,
                                    ArrivalTime        = adsbEvent.Timestamp,
                                    ArrivalAirport     = closestAirport.Identifier
                                });
                            }
                            // In any case, update the status for the new airport
                            flightStatus   = FlightStatus.Ground;
                            lastAirport    = closestAirport;
                            lastGroundTime = adsbEvent.Timestamp;
                        }
                        // If the aircraft is not close to an airport and was not previously flying, set the status to airborne
                        else if ((airportDistance > DistanceThreshold || altitudeDiff > AltitudeThreshold) && flightStatus != FlightStatus.Air)
                        {
                            flightStatus = FlightStatus.Air;
                        }
                        // Otherwise, assume no status change
                    }
                }

                // If all events have been read and the aircraft was last known to be flying, record a final flight with no arrival
                if (flightStatus == FlightStatus.Air)
                {
                    flights.Flights.Add(new Flight
                    {
                        AircraftIdentifier = identifier,
                        DepartureTime      = lastGroundTime,
                        DepartureAirport   = lastAirport.Identifier,
                        ArrivalTime        = DateTime.MaxValue,
                        ArrivalAirport     = null
                    });
                }
            }

            return(flights);
        }
コード例 #3
0
        private static void Execute()
        {
            // Load the airports
            AirportCollection airports = AirportCollection.LoadFromFile(AirportsFilePath);

            var fileLines = System.IO.File.ReadAllLines(AdsbEventsFilePath);

            Dictionary <string, List <AdsbEvent> > airplanes = new Dictionary <string, List <AdsbEvent> >();

            foreach (var line in fileLines)
            {
                string airplaneId = Events.AdsbEvent.FromJson(line).Identifier;
                if (airplanes.ContainsKey(airplaneId))
                {
                    airplanes[airplaneId].Add(Events.AdsbEvent.FromJson(line));
                }
                else
                {
                    List <AdsbEvent> tmpEventList = new List <AdsbEvent>()
                    {
                        Events.AdsbEvent.FromJson(line)
                    };
                    airplanes.Add(Events.AdsbEvent.FromJson(line).Identifier, tmpEventList);
                }
            }

            System.IO.StreamWriter outFile = new System.IO.StreamWriter(OutputFilePath);

            foreach (var key in airplanes.Keys)
            {
                // debug output
                // System.Console.WriteLine(key);
                // setting defaults
                DateTime      prevTime            = DateTime.Parse("1/01/2020 12:00:00 AM");
                GeoCoordinate prevAirportLocation = null;
                Airport       prevAirport         = null;
                Flight        flight = new Flight();
                flight.AircraftIdentifier = key;

                foreach (var adsbEventEntry in airplanes[key])
                {
                    // create a geolocation based on airplane adsb event coords
                    string        latLong          = adsbEventEntry.Latitude.ToString() + "," + adsbEventEntry.Longitude.ToString();
                    GeoCoordinate airplaneLocation = GeoCoordinate.FromLatitudeAndLongitudeString(latLong);
                    // get closest airport based on current airplane location
                    Airport tempAirport = airports.GetClosestAirport(airplaneLocation);
                    // create airport geolocation
                    string        airportLatLong  = tempAirport.Latitude.ToString() + "," + tempAirport.Longitude.ToString();
                    GeoCoordinate airportLocation = GeoCoordinate.FromLatitudeAndLongitudeString(airportLatLong);

                    // In order for an event to be a landing/takeoff:
                    // 1. geolocation within 5 miles of an airport (Flight safety, no unregistered aircraft within 5 miles of an airport)
                    // 2. altitude diff within 500 feet (safety altitude)
                    // 3. take off and landing speed < 200 mph

                    // In order for an airport to have a takeoff for this airplane:
                    // 1. The timestamp reads must have a difference > 30 mins

                    // Airplane heading and speed is not always present in adsbevent data, which means we can't rely on it to determine landing vs takeoff
                    double tempDist = airplaneLocation.GetDistanceTo(airportLocation);
                    if (tempDist < 5)
                    {
                        if (adsbEventEntry.Altitude != null && (adsbEventEntry.Altitude - tempAirport.Elevation <= 500) && adsbEventEntry.Speed != null && adsbEventEntry.Speed <= 200)
                        {
                            //did some reasearch, it looks like it takes the crew around 30-60 mins to get the plane checked again for next flight
                            if (adsbEventEntry.Timestamp - prevTime > TimeSpan.Parse("00:30:00"))
                            {
                                // logic for arrivals and departures
                                if (prevAirportLocation != null && prevAirportLocation != airportLocation)
                                {
                                    //only departure is added w/ previous timestamp
                                    flight.DepartureTime    = prevTime;
                                    flight.DepartureAirport = prevAirport.Identifier;
                                }
                                else if (prevAirportLocation == airportLocation)
                                {
                                    //arrival is added w/ previous timestamp
                                    flight.ArrivalTime    = prevTime;
                                    flight.ArrivalAirport = prevAirport.Identifier;
                                }
                            }
                            prevAirportLocation = airportLocation;
                            prevTime            = adsbEventEntry.Timestamp;
                            prevAirport         = tempAirport;
                        }
                    }

                    //record flights if arrival time is populated
                    if (flight.ArrivalAirport != null)
                    {
                        outFile.WriteLine(flight.ToString());
                        flight = new Flight();
                        flight.AircraftIdentifier = key;
                    }
                }
            }

            outFile.Close();
        }