using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TrainInfomationProviderService.StationInfo; using TrainInfomationProviderService.StationInfo.Entities; namespace TrainInfomationProviderService.TrainInfo.Entities { public class TrainTransitOnceResultCollection : ICollection { List _list = new List(); TrainTransitSearchOptions _options; /// /// 日期 /// public DateTime Date { get; private set; } /// /// 出发城市编码 /// public string FromCode { get; private set; } /// /// 到达城市编码 /// public string ToCode { get; private set; } /// /// 出发城市信息 /// public StationDetailInfo From { get; private set; } /// /// 到达城市信息 /// public StationDetailInfo To { get; private set; } /// /// 创建 的新实例(TrainTransitOnceResultCollection) /// /// /// /// /// public TrainTransitOnceResultCollection(DateTime date, TrainTransitSearchOptions options, string fromCode, string toCode) { ToCode = toCode; FromCode = fromCode; Date = date; _options = options; From = StationManager.Instance.Storage.Stations.GetValue(fromCode); To = StationManager.Instance.Storage.Stations.GetValue(toCode); } #region Implementation of IEnumerable /// /// 返回一个循环访问集合的枚举器。 /// /// /// 可用于循环访问集合的 。 /// public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } /// /// 返回一个循环访问集合的枚举数。 /// /// /// 一个可用于循环访问集合的 对象。 /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region Implementation of ICollection /// /// 将某项添加到 中。 /// /// 要添加到 的对象。 为只读。 public void Add(TrainTransitOnceResult item) { if (item == null || !CheckTransitLineAvailable(item)) return; _list.Add(item); } /// /// 从 中移除所有项。 /// /// 为只读。 public void Clear() { _list.Clear(); } /// /// 确定 是否包含特定值。 /// /// /// 如果在 中找到 ,则为 true;否则为 false。 /// /// 要在 中定位的对象。 public bool Contains(TrainTransitOnceResult item) { return _list.Contains(item); } /// /// 从特定的 索引开始,将 的元素复制到一个 中。 /// /// 作为从 复制的元素的目标的一维 必须具有从零开始的索引。 中从零开始的索引,从此索引处开始进行复制。 为 null。 小于 0。 中的元素数目大于从 到目标 末尾之间的可用空间。 public void CopyTo(TrainTransitOnceResult[] array, int arrayIndex) { _list.CopyTo(array, arrayIndex); } /// /// 从 中移除特定对象的第一个匹配项。 /// /// /// 如果已从 中成功移除 ,则为 true;否则为 false。 如果在原始 中没有找到 ,该方法也会返回 false。 /// /// 要从 中移除的对象。 为只读。 public bool Remove(TrainTransitOnceResult item) { return _list.Remove(item); } /// /// 获取 中包含的元素数。 /// /// /// 中包含的元素个数。 /// public int Count { get { return _list.Count; } } /// /// 获取一个值,该值指示 是否为只读。 /// /// /// 如果 为只读,则为 true;否则为 false。 /// public bool IsReadOnly { get { return false; } } public TrainTransitSearchOptions Options { get { return _options; } } #endregion #region 辅助函数 static int GetMinimalSpace(Train train, bool notRecommand) { var extraTime = notRecommand ? 60 : 0; switch (train.TrainClass) { case 'C': case 'G': return 30+extraTime; case 'D': return 30 + extraTime; case 'Z': return 60 + extraTime; case 'T': return 60 + extraTime; default: return 60 + extraTime; } } static int GetMaxiumSpace(Train train, bool notRecommand) { var extraTime = notRecommand ? 60 : 0; switch (train.TrainClass) { case 'C': case 'G': return 150 + extraTime; case 'D': return 150 + extraTime; case 'Z': return 180 + extraTime; case 'T': return 180 + extraTime; default: return 240 + extraTime; } } /// /// 获得比较理想中位时间 /// /// /// static int GetHighQualityTimeSpace(Train train, bool notRecommand) { var extraTime = notRecommand ? 60 : 0; switch (train.TrainClass) { case 'C': case 'G': return 60 + extraTime; case 'D': return 60 + extraTime; case 'Z': return 120 + extraTime; case 'T': return 120 + extraTime; default: return 120 + extraTime; } } #endregion #region 验证车次换乘是否有效 bool CheckTransitLineAvailable(TrainTransitOnceResult item) { //总共时间 if (item.First.CalculatedMinutesBase + item.Second.CalculatedMinutesBase > _options.MaxExtraMinutes) //时间过久 return false; //时间衔接 var arriveFirst = Date.Add(item.First.To.Arrive.Value); var leftSecond = arriveFirst.Date.Add(item.Second.From.Left.Value); //早于发车 if (leftSecond <= arriveFirst) return false; var space = (int)(leftSecond - arriveFirst).TotalMinutes; if (space < GetMinimalSpace(item.First.Train, item.NotRecommand) || space > GetMaxiumSpace(item.Second.Train, item.NotRecommand)) return false; return true; } #endregion #region 对列表进行二次优化 /// /// 二次优化,排除小站等。 /// internal void SecondaryAnalyze() { //对于前车进行分组优化 RemoveSmallStation(); //排序 ProcessPriority(); } /// /// 移除小站 /// void RemoveSmallStation() { var groups = this.GroupBy(s => s.First.Train.Code).Select(s => new { s.Key, Array = s.ToArray() }).ToArray(); foreach (var g in groups) { if (g.Array.Length < 2) continue; Array.Sort(g.Array, (s1, s2) => { var st1 = s1.First.To.StopTime.TotalMinutes; var st2 = s2.First.To.StopTime.TotalMinutes; if (st1 < st2) return 1; if (st1 > st2) return -1; return 0; }); foreach (var line in g.Array.Skip(Options.SameLineMaxKeepStations)) { _list.Remove(line); } } groups = this.GroupBy(s => s.Second.Train.Code).Select(s => new { s.Key, Array = s.ToArray() }).ToArray(); foreach (var g in groups) { if (g.Array.Length < 2) continue; Array.Sort(g.Array, (s1, s2) => { var st1 = s1.Second.From.StopTime.TotalMinutes; var st2 = s2.Second.From.StopTime.TotalMinutes; if (st1 < st2) return 1; if (st1 > st2) return -1; return 0; }); foreach (var line in g.Array.Skip(Options.SameLineMaxKeepStations)) { _list.Remove(line); } } } #endregion #region 分组排序 void ProcessPriority() { } #endregion } }