/// <summary> /// Returns a list of AirportLists given a route. "=>" is the separator between routes. This hits the database exactly once, for efficiency, and excludes duplicates. /// </summary> /// <param name="rgRoutes">The array of routes.</param> /// <param name="aplMaster">The "master" airportlist (contains all of the airports)</param> /// <returns>A list of airportlists; each contains at least one airport</returns> public static ListsFromRoutesResults ListsFromRoutes(IEnumerable <string> rgRoutes) { List <AirportList> lst = new List <AirportList>(); if (rgRoutes == null || !rgRoutes.Any()) { return(new ListsFromRoutesResults(lst, new AirportList(string.Empty))); } // Create a single "worker" airportlist from which we will create the others. AirportList aplMaster = new AirportList(String.Join(" ", rgRoutes.ToArray())); Dictionary <string, AirportList> dictRoutes = new Dictionary <string, AirportList>(); // Now create the resulting airport lists. Exclude duplicate routes foreach (string szRoute in rgRoutes) { string[] rgApCodeNormal = AirportList.NormalizeAirportList(szRoute); string szRouteKey = String.Join("", rgApCodeNormal); // skip duplicate routes if (dictRoutes.ContainsKey(szRouteKey)) { continue; } AirportList al = aplMaster.CloneSubset(rgApCodeNormal); if (al.m_rgAirports.Count > 0) { lst.Add(al); dictRoutes.Add(szRouteKey, al); } } return(new ListsFromRoutesResults(lst, aplMaster)); }
/// <summary> /// Returns a KML respresentation of all of the flights represented by the specified query /// </summary> /// <param name="fq">The flight query</param> /// <param name="s">The stream to which to write</param> /// <param name="error">Any error</param> /// <param name="lstIDs">The list of specific flight IDs to request</param> /// <returns>KML string for the matching flights.</returns> public static void AllFlightsAsKML(FlightQuery fq, Stream s, out string error, IEnumerable <int> lstIDs = null) { if (fq == null) { throw new ArgumentNullException(nameof(fq)); } if (String.IsNullOrEmpty(fq.UserName) && (lstIDs == null || !lstIDs.Any())) { throw new MyFlightbookException("Don't get all flights as KML for an empty user!!"); } if (lstIDs != null) { fq.EnumeratedFlights = lstIDs; } // Get the master airport list AirportList alMaster = AllFlightsAndNavaids(fq); using (KMLWriter kw = new KMLWriter(s)) { kw.BeginKML(); error = LookAtAllFlights( fq, LogbookEntryCore.LoadTelemetryOption.LoadAll, (le) => { if (le.Telemetry.HasPath) { using (FlightData fd = new FlightData()) { try { fd.ParseFlightData(le.Telemetry.RawData, le.Telemetry.MetaData); if (fd.HasLatLongInfo) { kw.AddPath(fd.GetTrajectory(), String.Format(CultureInfo.CurrentCulture, "{0:d} - {1}", le.Date, le.Comment), fd.SpeedFactor); return; } } catch (Exception ex) when(!(ex is OutOfMemoryException)) { } // eat any error and fall through below } } // No path was found above. AirportList al = alMaster.CloneSubset(le.Route); kw.AddRoute(al.GetNormalizedAirports(), String.Format(CultureInfo.CurrentCulture, "{0:d} - {1}", le.Date, le.Route)); }, lstIDs != null && lstIDs.Any()); kw.EndKML(); } }
/// <summary> /// Estimates the total distance flown by the user for the subset of flights described by the query /// </summary> /// <param name="fq">The flight query</param> /// <param name="fAutofillDistanceFlown">True to autofill the distance flown property if not found.</param> /// <param name="error">Any error</param> /// <returns>Distance flown, in nm</returns> public static double DistanceFlownByUser(FlightQuery fq, bool fAutofillDistanceFlown, out string error) { if (fq == null) { throw new ArgumentNullException(nameof(fq)); } if (String.IsNullOrEmpty(fq.UserName)) { throw new MyFlightbookException("Don't estimate distance for an empty user!!"); } double distance = 0.0; // Get the master airport list AirportList alMaster = AllFlightsAndNavaids(fq); error = LookAtAllFlights( fq, LogbookEntryCore.LoadTelemetryOption.MetadataOrDB, (le) => { double distThisFlight = 0; // If the trajectory had a distance, use it; otherwise, use airport-to-airport. double dPath = le.Telemetry.Distance(); if (dPath > 0) { distThisFlight = dPath; } else if (!String.IsNullOrEmpty(le.Route)) { distThisFlight = alMaster.CloneSubset(le.Route).DistanceForRoute(); } distance += distThisFlight; if (fAutofillDistanceFlown && distThisFlight > 0 && !le.CustomProperties.PropertyExistsWithID(CustomPropertyType.KnownProperties.IDPropDistanceFlown)) { le.CustomProperties.Add(CustomFlightProperty.PropertyWithValue(CustomPropertyType.KnownProperties.IDPropDistanceFlown, (decimal)distThisFlight)); le.FCommit(); } }); return(distance); }