using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using TrainInfomationProviderService.StationInfo; using TrainInfomationProviderService.TrainInfo.Entities; namespace TrainInfomationProviderService.TrainInfo { public class TrainInfoSearchProvider { #region 单例模式 static TrainInfoSearchProvider _instance; static readonly object _lockObject = new object(); public static TrainInfoSearchProvider Instance { get { if (_instance == null) { lock (_lockObject) { if (_instance == null) { _instance = new TrainInfoSearchProvider(); } } } return _instance; } } #endregion /// /// 是否已就绪 /// public bool IsReady { get; private set; } public IndexStorage Storage { get; private set; } public Dictionary> SameStationInfo { get; set; } private TrainInfoSearchProvider() { } public void Init() { Trace.TraceInformation("[TRAIN_INFO_SEARCH_PROVIDER] 正在创建车站-车次信息索引对象"); Storage = TrainInfoManager.Instance.IndexStorage; Trace.TraceInformation("[TRAIN_INFO_SEARCH_PROVIDER] 完成创建车站-车次信息索引对象"); IsReady = true; } public List FindDirectTrains(ref DateTime date, string from, string to) { TrainInfoStorage infoStorage = null; var minDate = DateTime.Now.Date; while (date >= minDate) { infoStorage = Storage.TrainInfoStorages.GetValue(date.ToString("yyyy-MM-dd")); if (infoStorage == null) date = date.AddDays(-1); else break; } var result = new List(); if (infoStorage == null) return result; for (var i = 0; i < infoStorage.Trains.Count; i++) { var train = infoStorage.Trains[i]; var stf = FindStop(train, from); if (stf == null) continue; var stt = FindStop(train, to); if (stt == null) continue; if (stf.Index >= stt.Index) continue; result.Add(new TrainLineSegment(train, stf, stt, date)); } return result; } public TrainTransitOnceResultCollection FindOnceTransitTrains(DateTime date, string from, string to, TrainTransitSearchOptions options) { TrainInfoStorage infoStorage = null; var minDate = DateTime.Now.Date; while (date >= minDate) { infoStorage = Storage.TrainInfoStorages.GetValue(date.ToString("yyyy-MM-dd")); if (infoStorage == null) date = date.AddDays(-1); else break; } if (infoStorage == null) return null; var result = new TrainTransitOnceResultCollection(date, options, from, to); //发车经过车站 var fromStations = GetSameStations(from); var toStations = GetSameStations(to); var fromTrains = fromStations.Select(s => infoStorage.StationLeftTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray(); var toTrains = toStations.Select(s => infoStorage.StationArriveTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray(); foreach (var fromTrain in fromTrains) { var startStop = FindStop(fromTrain, from); foreach (var fstop in fromTrain.TrainStops.SkipWhile(x => startStop != x).Skip(1).Where(s => s != null && !string.IsNullOrEmpty(s.Code))) { foreach (var toTrain in toTrains) { var toStop = FindStop(toTrain, to); foreach (var tStop in toTrain.TrainStops.TakeWhile(x => toStop != x).Where(s => s != null && !string.IsNullOrEmpty(s.Code))) { if (fstop.Code == tStop.Code) { var firstTrain = new TrainLineSegment(fromTrain, startStop, fstop, date); var secondTrain = new TrainLineSegment(toTrain, tStop, toStop, firstTrain.ArriveTime); //一个中转点 var line = new TrainTransitOnceResult( firstTrain, secondTrain, date ); result.Add(line); break; } if (IsStopInclude(fstop.Code, tStop.Code)) { var firstTrain = new TrainLineSegment(fromTrain, startStop, fstop, date); var secondTrain = new TrainLineSegment(toTrain, tStop, toStop, firstTrain.ArriveTime); //一个中转点 var line = new TrainTransitOnceResult( firstTrain, secondTrain, date, true ); result.Add(line); break; } } } } } result.SecondaryAnalyze(); return result; } HashSet GetSameStations(string code) { var map = SameStationManager.SameStationMap; if (map != null) { var hash = map.GetValue(code); if (hash != null) return hash; } return new HashSet() { code }; } bool IsStopInclude(string code1, string code2) { var map = SameStationManager.SameStationMap; if (map == null) return false; var set = map.GetValue(code1); return set != null && set.Contains(code2); } TrainStop FindStop(Train train, string code) { if (train == null || train.TrainStopMap == null) return null; var stop = train.TrainStopMap.GetValue(code); if (stop != null) return stop; var map = SameStationManager.SameStationMap; if (map == null) return null; var hash = map.GetValue(code); if (hash == null) return null; foreach (var s in hash) { stop = train.TrainStopMap.GetValue(s); if (stop != null) return stop; } return null; } } }