418 lines
12 KiB
C#
418 lines
12 KiB
C#
|
namespace Web12306.Servers.TrainSuggestion
|
|||
|
{
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Web;
|
|||
|
using System.Web.Hosting;
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Serialization;
|
|||
|
|
|||
|
public class TrainSuggestionHandler : IHttpHandler
|
|||
|
{
|
|||
|
#region Implementation of IHttpHandler
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// ͨ<><CDA8>ʵ<EFBFBD><CAB5> <see cref="T:System.Web.IHttpHandler"/> <20>ӿڵ<D3BF><DAB5>Զ<EFBFBD><D4B6><EFBFBD> HttpHandler <20><><EFBFBD><EFBFBD> HTTP Web <20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
/// </summary>
|
|||
|
/// <param name="context"><see cref="T:System.Web.HttpContext"/> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ HTTP <20><><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Request<73><74>Response<73><65>Session <20><> Server<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD></param>
|
|||
|
public void ProcessRequest(HttpContext context)
|
|||
|
{
|
|||
|
var request = context.Request;
|
|||
|
context.Response.StatusCode = 404;
|
|||
|
if (request.UrlReferrer == null || !Regex.IsMatch(request.UrlReferrer.Host, @"^.*?\.(fishlee\.net|liebao\.cn)$"))
|
|||
|
return;
|
|||
|
|
|||
|
//check code
|
|||
|
var r = request.QueryString["r"];
|
|||
|
if (string.IsNullOrEmpty(r))
|
|||
|
return;
|
|||
|
|
|||
|
var data = request.Form["data"];
|
|||
|
if (string.IsNullOrEmpty(data))
|
|||
|
return;
|
|||
|
|
|||
|
var crc = GetTextCrc(data);
|
|||
|
if (!r.EndsWith(crc + ""))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
var origin = request.Headers["Origin"];
|
|||
|
var callback = request.QueryString["calllback"];
|
|||
|
if (!string.IsNullOrEmpty(origin))
|
|||
|
{
|
|||
|
if (Regex.IsMatch(origin, @"^(https?://.*?\.(fishlee\.net|liebao\.cn)|chrome-extension://.*)$"))
|
|||
|
context.Response.AddHeader("Access-Control-Allow-Origin", origin);
|
|||
|
else
|
|||
|
{
|
|||
|
//<2F>Ƿ<EFBFBD><C7B7>ύ
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
context.Response.ContentType = string.IsNullOrEmpty(callback) ? "application/json" : "application/javascript";
|
|||
|
context.Response.BufferOutput = true;
|
|||
|
context.Response.StatusCode = 200;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
var ri = JsonConvert.DeserializeObject<RequestInfo>(data);
|
|||
|
var suggestion = GetSuggestionResponseContent(ri);
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(callback))
|
|||
|
{
|
|||
|
context.Response.Write(callback + "(");
|
|||
|
}
|
|||
|
context.Response.Write(suggestion);
|
|||
|
if (!string.IsNullOrEmpty(callback))
|
|||
|
{
|
|||
|
context.Response.Write(callback + ");");
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
//log error
|
|||
|
var sb = new StringBuilder();
|
|||
|
sb.AppendLine(string.Format("<22><><EFBFBD><EFBFBD>URL<52><4C> {0}", context.Request.Url));
|
|||
|
sb.AppendLine("<22><><EFBFBD><EFBFBD>:");
|
|||
|
sb.AppendLine(data);
|
|||
|
sb.AppendLine();
|
|||
|
|
|||
|
sb.AppendLine("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ:");
|
|||
|
sb.AppendLine(ex.ToString());
|
|||
|
|
|||
|
var log = DateTime.Now.Ticks + ".log";
|
|||
|
var path = HostingEnvironment.MapPath("~/errors/tr/");
|
|||
|
path = PathUtility.Combine(path, log);
|
|||
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|||
|
File.WriteAllText(path, sb.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int GetTextCrc(string txt)
|
|||
|
{
|
|||
|
var crc = 0;
|
|||
|
for (var i = 0; i < txt.Length - 1; i += 2)
|
|||
|
{
|
|||
|
crc += txt[i] ^ txt[i + 1];
|
|||
|
if (crc > 48360)
|
|||
|
crc -= 36048;
|
|||
|
}
|
|||
|
if (txt.Length % 2 == 1)
|
|||
|
crc += txt[txt.Length - 1];
|
|||
|
if (crc > 48360)
|
|||
|
crc -= 36048;
|
|||
|
crc = crc ^ 5299;
|
|||
|
|
|||
|
return crc;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><>ȡһ<C8A1><D2BB>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵָʾ<D6B8><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> <see cref="T:System.Web.IHttpHandler"/> ʵ<><CAB5><EFBFBD><EFBFBD>
|
|||
|
/// </summary>
|
|||
|
/// <returns>
|
|||
|
/// <20><><EFBFBD><EFBFBD> <see cref="T:System.Web.IHttpHandler"/> ʵ<><CAB5><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD>Ϊ true<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ false<73><65>
|
|||
|
/// </returns>
|
|||
|
public bool IsReusable { get { return true; } }
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region <EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
static JsonSerializerSettings _camelJsonSetting = new JsonSerializerSettings
|
|||
|
{
|
|||
|
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
|||
|
};
|
|||
|
|
|||
|
string GetSuggestionResponseContent(RequestInfo ri)
|
|||
|
{
|
|||
|
if (ri.CheckIllegal())
|
|||
|
return string.Empty;
|
|||
|
|
|||
|
return JsonConvert.SerializeObject(GetSuggestionResponseContentCore(ri), Formatting.None, _camelJsonSetting);
|
|||
|
}
|
|||
|
|
|||
|
SuggestionResponse GetSuggestionResponseContentCore(RequestInfo ri)
|
|||
|
{
|
|||
|
//Ԥ<><D4A4><EFBFBD><EFBFBD>
|
|||
|
PreProcessRequestData(ri);
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĿ<D0B5><C4BF>滻վ<E6BBBB><D5BE>
|
|||
|
var alllines = ri.Stops.Values.SelectMany(s => GetAlternativeLines(s, ri.Date) ?? new List<AlternativeLine>()).Where(s => s != null).ToArray();
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
var lineGrouped = alllines.GroupBy(s => s.LineName).Select(s =>
|
|||
|
{
|
|||
|
var list = s.ToList();
|
|||
|
var f = list[0];
|
|||
|
return new AlternativeLineGroup(f.From.Name, f.To.Name, f.Date, list, f.IsCrossDate);
|
|||
|
}).ToList();
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
FilteAlternativeLine(ri, lineGrouped);
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
FillExtraInfo(ri, lineGrouped);
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
SortLineRecommand(ri, lineGrouped);
|
|||
|
|
|||
|
return new SuggestionResponse()
|
|||
|
{
|
|||
|
Key = "<22><><EFBFBD>ÿɳܣ<C9B3><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵĸ<DCB5><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ITͬ<54>У<EFBFBD>",
|
|||
|
Accepted = true,
|
|||
|
Groups = lineGrouped
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
void PreProcessRequestData(RequestInfo ri)
|
|||
|
{
|
|||
|
ri.PreprocessData();
|
|||
|
}
|
|||
|
|
|||
|
void FilteAlternativeLine(RequestInfo ri, List<AlternativeLineGroup> line)
|
|||
|
{
|
|||
|
for (var i = line.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
var train = ri.Stops[line[i].Lines[0].TrainCode];
|
|||
|
|
|||
|
var maxAllowElapsedTime = train.TrainInfo.elapsedTime.Value.Add(train.TrainInfo.elapsedTime.MaxAddTime);
|
|||
|
for (var j = line[i].Lines.Count - 1; j >= 0; j--)
|
|||
|
{
|
|||
|
var current = line[i].Lines[j];
|
|||
|
//<2F><><EFBFBD><EFBFBD>ͬʱ<CDAC>Ƿ<EFBFBD>վ<EFBFBD>͵<EFBFBD>վ<EFBFBD><D5BE><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD>
|
|||
|
if (current.From.IsOriginal && current.To.IsOriginal)
|
|||
|
line[i].Lines.RemoveAt(j);
|
|||
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ᳬ<EFBFBD><E1B3AC>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD>
|
|||
|
else if (current.ElapsedTime > maxAllowElapsedTime)
|
|||
|
line[i].Lines.RemoveAt(j);
|
|||
|
}
|
|||
|
if (line[i].Lines.Count == 0)
|
|||
|
{
|
|||
|
line.RemoveAt(i);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>վ<EFBFBD><D5BE><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8>
|
|||
|
/// </summary>
|
|||
|
/// <param name="lineList"></param>
|
|||
|
/// <returns></returns>
|
|||
|
int GetLineStationEndpointWeight(List<AlternativeLine> lineList)
|
|||
|
{
|
|||
|
var point = 0;
|
|||
|
foreach (var line in lineList)
|
|||
|
{
|
|||
|
if (line.From.IsEndPoint && line.To.IsEndPoint)
|
|||
|
point += 2;
|
|||
|
else if (line.From.IsEndPoint || line.To.IsEndPoint)
|
|||
|
point += 1;
|
|||
|
}
|
|||
|
return point;
|
|||
|
}
|
|||
|
|
|||
|
void SortLineRecommand(RequestInfo ri, List<AlternativeLineGroup> line)
|
|||
|
{
|
|||
|
line.Sort((x, y) =>
|
|||
|
{
|
|||
|
var ceo1 = GetLineStationEndpointWeight(x.Lines);
|
|||
|
var ceo2 = GetLineStationEndpointWeight(y.Lines);
|
|||
|
if (ceo1 != ceo2)
|
|||
|
return ceo2 - ceo1;
|
|||
|
|
|||
|
if (x.Lines.Count != y.Lines.Count)
|
|||
|
return y.Lines.Count - x.Lines.Count;
|
|||
|
|
|||
|
//<2F>ٿ<EFBFBD>ͣ<EFBFBD><CDA3>ʱ<EFBFBD><CAB1>
|
|||
|
var ep1 = (int)x.Lines.Min(s => s.From.StopTime + s.To.StopTime).TotalSeconds;
|
|||
|
var ep2 = (int)y.Lines.Min(s => s.From.StopTime + s.To.StopTime).TotalSeconds;
|
|||
|
if (ep1 != ep2)
|
|||
|
return ep2 - ep1;
|
|||
|
|
|||
|
|
|||
|
//<2F>ٿ<EFBFBD><D9BF>۸<EFBFBD>
|
|||
|
var ap1 = x.Lines.Min(s => s.Radio);
|
|||
|
var ap2 = y.Lines.Min(s => s.Radio);
|
|||
|
if (ap1 != ap2)
|
|||
|
return ap1 - ap2;
|
|||
|
|
|||
|
return 0;
|
|||
|
});
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD>5<EFBFBD><35><EFBFBD><EFBFBD>·
|
|||
|
if (line.Count > 5)
|
|||
|
line.RemoveRange(5, line.Count - 5);
|
|||
|
|
|||
|
//<2F>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
foreach (var current in line)
|
|||
|
{
|
|||
|
current.Lines.Sort((x, y) =>
|
|||
|
{
|
|||
|
//<2F>ٿ<EFBFBD>ͣ<EFBFBD><CDA3>ʱ<EFBFBD><CAB1>
|
|||
|
var ep1 = (int)(x.From.StopTime + x.To.StopTime).TotalSeconds;
|
|||
|
var ep2 = (int)(y.From.StopTime + y.To.StopTime).TotalSeconds;
|
|||
|
if (ep1 != ep2)
|
|||
|
return ep2 - ep1;
|
|||
|
|
|||
|
//<2F>ٿ<EFBFBD><D9BF>۸<EFBFBD>
|
|||
|
var ap1 = (int)x.ExtraPrice;
|
|||
|
var ap2 = (int)y.ExtraPrice;
|
|||
|
if (ap1 != ap2)
|
|||
|
return ap1 - ap2;
|
|||
|
|
|||
|
return 0;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void FillExtraInfo(RequestInfo ri, List<AlternativeLineGroup> line)
|
|||
|
{
|
|||
|
for (var i = line.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
for (var j = line[i].Lines.Count - 1; j >= 0; j--)
|
|||
|
{
|
|||
|
var train = ri.Stops[line[i].Lines[j].TrainCode];
|
|||
|
var current = line[i].Lines[j];
|
|||
|
var originalTime = train.TrainInfo.elapsedTime.Value;
|
|||
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ᳬ<EFBFBD><E1B3AC>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD>
|
|||
|
var priceExtraRadio = ((current.ElapsedTime - originalTime).TotalSeconds / (1.0 * originalTime.TotalSeconds));
|
|||
|
current.BasePriceSeat = Cn12306SuggestionUtility.BaseSeatCodes.First(s => train.TrainInfo.ticketMap.ContainsKey(s));
|
|||
|
current.BasePrice = train.TrainInfo.ticketMap[current.BasePriceSeat].price / 10.0;
|
|||
|
current.ExtraPrice = Math.Round(priceExtraRadio * current.BasePrice, 2);
|
|||
|
current.Radio = (int)(priceExtraRadio * 100);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
List<AlternativeLine> GetAlternativeLines(TrainInfoItem train, DateTime requestDate)
|
|||
|
{
|
|||
|
var info = train.TrainInfo;
|
|||
|
var stops = train.StopInfos;
|
|||
|
|
|||
|
var indexFrom = Array.FindIndex(stops, s => s.station_name == info.from.name);
|
|||
|
var indexTo = Array.FindIndex(stops, indexFrom + 1, s => s.station_name == info.to.name);
|
|||
|
|
|||
|
if (indexFrom == -1 || indexTo == -1)
|
|||
|
return null;
|
|||
|
|
|||
|
var altFrom = new List<AlternativeStation>();
|
|||
|
var altTo = new List<AlternativeStation>();
|
|||
|
var maxAddTime = train.TrainInfo.elapsedTime.MaxAddTime;
|
|||
|
|
|||
|
if (indexFrom != 0)
|
|||
|
{
|
|||
|
var stopTimeFrom = stops[indexFrom].StopTime;
|
|||
|
var arriveTime = stops[indexFrom].ArriveTime;
|
|||
|
for (var i = 0; i < indexFrom; i++)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD><EFBFBD>isEnabledΪtrue<75><65><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>վ<EFBFBD>㡣<EFBFBD><E3A1A3><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD>̵ġ<CCB5>
|
|||
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD>
|
|||
|
if (stops[i].isEnabled || stops[i].StartTime - arriveTime > maxAddTime)
|
|||
|
continue;
|
|||
|
|
|||
|
var stopTime = i == 0 ? TimeSpan.Zero : stops[i].StopTime;
|
|||
|
if (i != 0)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD>ڷ<EFBFBD>ʼ<EFBFBD><CABC>վ<EFBFBD><D5BE>ͣ<EFBFBD><CDA3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
|
|||
|
if (stopTime < stopTimeFrom && i < indexFrom - 3)
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//<2F><><EFBFBD>ӵ<EFBFBD><D3B5>Ƽ<EFBFBD><C6BC>б<EFBFBD><D0B1><EFBFBD>
|
|||
|
altFrom.Add(new AlternativeStation()
|
|||
|
{
|
|||
|
ArriveTime = stops[i].StartTime,
|
|||
|
IsEndPoint = i == 0,
|
|||
|
IsFromStation = true,
|
|||
|
Name = stops[i].station_name,
|
|||
|
StopTime = stopTime,
|
|||
|
TrainID = info.id,
|
|||
|
TrainCode = info.code,
|
|||
|
Date = stops[i].StartTime,
|
|||
|
IsCrossDate = requestDate != stops[i].StartTime.Date
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
altFrom.Sort(new AlternativeStationComparer());
|
|||
|
if (altFrom.Count > 5)
|
|||
|
altFrom.RemoveRange(5, altFrom.Count - 5);
|
|||
|
}
|
|||
|
if (indexTo != stops.Length - 1)
|
|||
|
{
|
|||
|
var stopTimeTo = stops[indexTo].StopTime;
|
|||
|
var startTime = stops[indexTo].StartTime;
|
|||
|
|
|||
|
for (var i = stops.Length - 1; i >= indexTo; i--)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD><EFBFBD>isEnabledΪtrue<75><65><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>վ<EFBFBD>㡣<EFBFBD><E3A1A3><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD>̵ġ<CCB5>
|
|||
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD>
|
|||
|
if (stops[i].isEnabled || stops[i].ArriveTime - startTime > maxAddTime)
|
|||
|
continue;
|
|||
|
|
|||
|
var stopTime = i == 0 ? TimeSpan.Zero : stops[i].StopTime;
|
|||
|
if (i != stops.Length - 1)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD>ڷ<EFBFBD><DAB7>յ<EFBFBD>վ<EFBFBD><D5BE>ͣ<EFBFBD><CDA3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƽ<EFBFBD><C6BC><EFBFBD>
|
|||
|
if (stopTime < stopTimeTo && i > indexTo + 3)
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//<2F><><EFBFBD>ӵ<EFBFBD><D3B5>Ƽ<EFBFBD><C6BC>б<EFBFBD><D0B1><EFBFBD>
|
|||
|
altTo.Add(new AlternativeStation()
|
|||
|
{
|
|||
|
ArriveTime = stops[i].ArriveTime,
|
|||
|
IsEndPoint = i == stops.Length - 1,
|
|||
|
IsFromStation = false,
|
|||
|
Name = stops[i].station_name,
|
|||
|
TrainID = info.id,
|
|||
|
StopTime = stopTime,
|
|||
|
TrainCode = info.code
|
|||
|
});
|
|||
|
}
|
|||
|
altTo.Sort(new AlternativeStationComparer());
|
|||
|
if (altTo.Count > 5)
|
|||
|
altTo.RemoveRange(5, altTo.Count - 5);
|
|||
|
}
|
|||
|
//plus ԭʼ<D4AD><CABC>·
|
|||
|
altFrom.Add(new AlternativeStation
|
|||
|
{
|
|||
|
ArriveTime = stops[indexFrom].StartTime,
|
|||
|
IsEndPoint = indexFrom == 0,
|
|||
|
IsFromStation = true,
|
|||
|
Name = stops[indexFrom].station_name,
|
|||
|
StopTime = indexFrom == 0 ? TimeSpan.Zero : stops[indexFrom].StopTime,
|
|||
|
TrainCode = info.code,
|
|||
|
IsOriginal = true,
|
|||
|
TrainID = info.id,
|
|||
|
IsCrossDate = false,
|
|||
|
Date = stops[indexFrom].StartTime
|
|||
|
});
|
|||
|
|
|||
|
altTo.Add(new AlternativeStation
|
|||
|
{
|
|||
|
ArriveTime = stops[indexTo].ArriveTime,
|
|||
|
IsEndPoint = indexTo == stops.Length - 1,
|
|||
|
IsFromStation = false,
|
|||
|
TrainID = info.id,
|
|||
|
Name = stops[indexTo].station_name,
|
|||
|
StopTime = indexTo == stops.Length - 1 ? TimeSpan.Zero : stops[indexFrom].StopTime,
|
|||
|
TrainCode = info.code,
|
|||
|
IsOriginal = true
|
|||
|
});
|
|||
|
|
|||
|
var lines = altFrom.CrossJoin(altTo).Where(s => !s.Key.IsOriginal || !s.Value.IsOriginal).Select(s => new AlternativeLine(s.Key, s.Value, s.Key.Date, s.Key.IsCrossDate) { TrainCode = s.Key.TrainCode, TrainId = s.Key.TrainID }).ToList();
|
|||
|
return lines;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
}
|