Light12306/TrainInfomationProviderService/TrainInfo/TrainInfoSearchProvider.cs

217 lines
5.4 KiB
C#
Raw Normal View History

2014-11-21 20:32:36 +08:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
2014-11-27 23:25:36 +08:00
using TrainInfomationProviderService.StationInfo;
2014-11-21 20:32:36 +08:00
using TrainInfomationProviderService.TrainInfo.Entities;
namespace TrainInfomationProviderService.TrainInfo
{
public class TrainInfoSearchProvider
{
2014-12-01 21:50:08 +08:00
#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
/// <summary>
/// 是否已就绪
/// </summary>
public bool IsReady { get; private set; }
2014-11-21 20:32:36 +08:00
public IndexStorage Storage { get; private set; }
2014-11-27 23:25:36 +08:00
public Dictionary<string, HashSet<string>> SameStationInfo { get; set; }
2014-12-01 21:50:08 +08:00
private TrainInfoSearchProvider()
{
}
public void Init()
2014-11-21 20:32:36 +08:00
{
Trace.TraceInformation("[TRAIN_INFO_SEARCH_PROVIDER] 正在创建车站-车次信息索引对象");
2014-12-01 02:17:13 +08:00
Storage = TrainInfoManager.Instance.IndexStorage;
2014-11-21 20:32:36 +08:00
Trace.TraceInformation("[TRAIN_INFO_SEARCH_PROVIDER] 完成创建车站-车次信息索引对象");
2014-12-01 21:50:08 +08:00
IsReady = true;
2014-11-21 20:32:36 +08:00
}
2014-11-27 23:25:36 +08:00
2014-12-01 21:50:08 +08:00
public List<TrainLineSegment> FindDirectTrains(ref DateTime date, string from, string to)
2014-11-27 23:25:36 +08:00
{
2014-12-01 21:50:08 +08:00
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<TrainLineSegment>();
2014-11-27 23:25:36 +08:00
if (infoStorage == null)
2014-12-01 21:50:08 +08:00
return result;
2014-11-27 23:25:36 +08:00
2014-12-01 21:50:08 +08:00
for (var i = 0; i < infoStorage.Trains.Count; i++)
2014-11-27 23:25:36 +08:00
{
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;
2014-12-01 21:50:08 +08:00
result.Add(new TrainLineSegment(train, stf, stt, date));
2014-11-27 23:25:36 +08:00
}
2014-12-01 21:50:08 +08:00
return result;
2014-11-27 23:25:36 +08:00
}
public TrainTransitOnceResultCollection FindOnceTransitTrains(DateTime date, string from, string to, TrainTransitSearchOptions options)
{
2014-12-01 21:50:08 +08:00
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;
}
2014-11-27 23:25:36 +08:00
if (infoStorage == null)
2014-12-01 21:50:08 +08:00
return null;
var result = new TrainTransitOnceResultCollection(date, options, from, to);
2014-11-27 23:25:36 +08:00
//发车经过车站
var fromStations = GetSameStations(from);
var toStations = GetSameStations(to);
var fromTrains = fromStations.Select(s => infoStorage.StationLeftTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray();
2014-12-05 23:32:41 +08:00
var toTrains = toStations.Select(s => infoStorage.StationArriveTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToArray();
2014-11-27 23:25:36 +08:00
foreach (var fromTrain in fromTrains)
{
var startStop = FindStop(fromTrain, from);
2014-12-05 23:32:41 +08:00
foreach (var fstop in fromTrain.TrainStops.SkipWhile(x => startStop != x).Skip(1).Where(s => s != null && !string.IsNullOrEmpty(s.Code)))
2014-11-27 23:25:36 +08:00
{
foreach (var toTrain in toTrains)
{
var toStop = FindStop(toTrain, to);
2014-12-05 23:32:41 +08:00
foreach (var tStop in toTrain.TrainStops.TakeWhile(x => toStop != x).Where(s => s != null && !string.IsNullOrEmpty(s.Code)))
2014-11-27 23:25:36 +08:00
{
if (fstop.Code == tStop.Code)
{
2014-12-01 21:50:08 +08:00
var firstTrain = new TrainLineSegment(fromTrain, startStop, fstop, date);
var secondTrain = new TrainLineSegment(toTrain, tStop, toStop, firstTrain.ArriveTime);
2014-11-27 23:25:36 +08:00
//一个中转点
var line = new TrainTransitOnceResult(
2014-12-01 21:50:08 +08:00
firstTrain,
secondTrain,
2014-11-27 23:25:36 +08:00
date
);
result.Add(line);
2014-12-01 02:17:13 +08:00
break;
2014-11-27 23:25:36 +08:00
}
2014-12-01 02:17:13 +08:00
if (IsStopInclude(fstop.Code, tStop.Code))
2014-11-27 23:25:36 +08:00
{
2014-12-01 21:50:08 +08:00
var firstTrain = new TrainLineSegment(fromTrain, startStop, fstop, date);
var secondTrain = new TrainLineSegment(toTrain, tStop, toStop, firstTrain.ArriveTime);
2014-11-27 23:25:36 +08:00
//一个中转点
var line = new TrainTransitOnceResult(
2014-12-01 21:50:08 +08:00
firstTrain,
secondTrain,
2014-11-27 23:25:36 +08:00
date,
true
);
result.Add(line);
2014-12-01 02:17:13 +08:00
break;
2014-11-27 23:25:36 +08:00
}
}
}
}
}
result.SecondaryAnalyze();
return result;
}
HashSet<string> GetSameStations(string code)
{
var map = SameStationManager.SameStationMap;
if (map != null)
{
var hash = map.GetValue(code);
if (hash != null)
return hash;
}
return new HashSet<string>() { 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;
}
2014-11-21 20:32:36 +08:00
}
}