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
|
|
|
|
|
{
|
2014-12-08 01:06:01 +08:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
2014-11-21 20:32:36 +08:00
|
|
|
|
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"));
|
2015-12-07 02:30:22 +08:00
|
|
|
|
if (infoStorage == null || infoStorage.Trains.Count == 0)
|
2014-12-01 21:50:08 +08:00
|
|
|
|
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"));
|
2015-12-07 02:30:22 +08:00
|
|
|
|
if (infoStorage == null || infoStorage.Trains.Count == 0)
|
2014-12-01 21:50:08 +08:00
|
|
|
|
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);
|
2015-10-21 12:40:04 +08:00
|
|
|
|
var fromTrains = fromStations.Select(s => infoStorage.StationLeftTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToHashSet();
|
|
|
|
|
var toTrains = toStations.Select(s => infoStorage.StationArriveTrainData.GetValue(s)).ExceptNull().SelectMany(s => s).ToHashSet();
|
|
|
|
|
|
|
|
|
|
//排除交集
|
|
|
|
|
var exclude = fromTrains.Intersect(toTrains).ToHashSet();
|
|
|
|
|
exclude.ForEach(s =>
|
|
|
|
|
{
|
|
|
|
|
fromTrains.Remove(s);
|
|
|
|
|
toTrains.Remove(s);
|
|
|
|
|
});
|
2014-11-27 23:25:36 +08:00
|
|
|
|
|
|
|
|
|
foreach (var fromTrain in fromTrains)
|
|
|
|
|
{
|
|
|
|
|
var startStop = FindStop(fromTrain, from);
|
2015-10-21 12:40:04 +08:00
|
|
|
|
|
|
|
|
|
//如果这车过终点站,则忽略
|
|
|
|
|
if (FindStop(fromTrain, to) != null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2015-10-21 12:40:04 +08:00
|
|
|
|
//如果这车过发车站,则忽略
|
|
|
|
|
if (FindStop(toTrain, from) != null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-27 23:25:36 +08:00
|
|
|
|
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
|
|
|
|
{
|
2014-12-08 01:06:01 +08:00
|
|
|
|
try
|
2014-11-27 23:25:36 +08:00
|
|
|
|
{
|
2014-12-08 01:06:01 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2014-11-27 23:25:36 +08:00
|
|
|
|
}
|
2014-12-08 01:06:01 +08:00
|
|
|
|
catch (Exception ex)
|
2014-11-27 23:25:36 +08:00
|
|
|
|
{
|
2014-12-08 01:06:01 +08:00
|
|
|
|
var msg = new StringBuilder(0x400);
|
|
|
|
|
msg.AppendLine("无法创建检测,错误信息:" + ex.ToString() + "\r\n\r\n相关数据:\r\n=====================\r\n");
|
|
|
|
|
msg.Append("前车:");
|
|
|
|
|
msg.AppendLine(fromTrain == null ? "null" : JsonConvert.SerializeObject(fromTrain));
|
|
|
|
|
msg.Append("前车发站:");
|
|
|
|
|
msg.AppendLine(startStop == null ? "null" : JsonConvert.SerializeObject(startStop));
|
|
|
|
|
msg.Append("前车到站:");
|
|
|
|
|
msg.AppendLine(fstop == null ? "null" : JsonConvert.SerializeObject(fstop));
|
|
|
|
|
msg.Append("后车:");
|
|
|
|
|
msg.AppendLine(toTrain == null ? "null" : JsonConvert.SerializeObject(toTrain));
|
|
|
|
|
msg.Append("后车发站:");
|
|
|
|
|
msg.AppendLine(tStop == null ? "null" : JsonConvert.SerializeObject(tStop));
|
|
|
|
|
msg.Append("后车到站:");
|
|
|
|
|
msg.AppendLine(toStop == null ? "null" : JsonConvert.SerializeObject(toStop));
|
|
|
|
|
msg.Append("前车发站:");
|
|
|
|
|
msg.AppendLine(startStop == null ? "null" : JsonConvert.SerializeObject(startStop));
|
|
|
|
|
|
|
|
|
|
throw new Exception(msg.ToString(), ex);
|
2014-11-27 23:25:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-08 01:06:01 +08:00
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
}
|