public virtual RouteSearchResult SearchRoute(string from, string to, DayType daytype) { var instance = DBModel.GetInstance(); var fromStation = instance.Stations.Where(c => c.Key == from).Select(c => c.Value).SingleOrDefault(); var toStation = instance.Stations.Where(c => c.Key == to).Select(c => c.Value).SingleOrDefault(); if (fromStation == null || toStation == null) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); } var result = new RouteSearchResult() { FromStation = new StationIdNamePair() { Id = from, Name = fromStation.Name, Yomi = fromStation.Yomi }, ToStation = new StationIdNamePair() { Id = to, Name = toStation.Name, Yomi = toStation.Yomi }, QueryDayType = daytype }; result.Routes = (from busSet in fromStation.Buses.Where(c => c.DayType == daytype) .Join(toStation.Buses, f => f.BusId, t => t.BusId, (f, t) => new { From = f, To = t }) let bus = instance.Buses[busSet.From.BusId] let line = instance.Lines.GetDataFromDayType(daytype)[bus.LineId] where line.Stations.IndexOf(@from) < line.Stations.LastIndexOf(to) let dept = Commons.ConvertToTimeSpan(busSet.From.DeptTime) let arr = Commons.ConvertToTimeSpan(busSet.To.DeptTime) where dept <= arr let time = Commons.ConvertToString(Commons.DiffTimespan(dept, arr)) select new Route() { Pathes = new List<Path>() { new Path() { DeptNode = new Node() { Station = result.FromStation, Time = busSet.From.DeptTime }, ArrNode = new Node() { Station = result.ToStation, Time = busSet.To.DeptTime }, Method = TransferMethod.Bus, Line = new LineNameInfo() { Id = bus.LineId, Name = line.Name, Number = line.Number }, BusId = busSet.From.BusId, Time = time } }, Rank = 1.0, TotalDeptTime = busSet.From.DeptTime, TotalArrTime = busSet.To.DeptTime, TransferCount = 0, TotalTime = time }).ToList(); return result; }
public virtual RouteSearchResult SearchRoute(string from, string to, DayType daytype,RouteSeachMethod method = RouteSeachMethod.DepartureBase, string queryTime = null, int count = 5) { var instance = DBModel.GetInstance(); // deptがnullなら現在時刻 TimeSpan baseTime = DateTime.Now.TimeOfDay; if (queryTime != null && queryTime != String.Empty) { baseTime = Commons.ConvertToTimeSpan(queryTime); if (baseTime == TimeSpan.Zero) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest)); } } else { method = RouteSeachMethod.DepartureBase; } var fromStation = instance.Stations.Where(c => c.Key == from).Select(c => c.Value).SingleOrDefault(); var toStation = instance.Stations.Where(c => c.Key == to).Select(c => c.Value).SingleOrDefault(); if (fromStation == null || toStation == null) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); } var result = new RouteSearchResult() { FromStation = new StationIdNamePair() { Id = from, Name = fromStation.Name, Yomi = fromStation.Yomi }, ToStation = new StationIdNamePair() { Id = to, Name = toStation.Name, Yomi = toStation.Yomi }, QueryDayType = daytype, QueryMethod = method, QueryTime = Commons.ConvertToString(baseTime) }; IEnumerable<Tuple<BusDeptTimeInfo, BusDeptTimeInfo>> tempSource = null; if (method == RouteSeachMethod.DepartureBase) { // 発検索 -> fromの発車時刻がクエリとして与えられた時刻よりも新しい tempSource = fromStation.Buses.Where(c => c.DayType == daytype && Commons.ConvertToTimeSpan(c.DeptTime) >= baseTime) .Join(toStation.Buses, f => f.BusId, t => t.BusId, (f, t) => new Tuple<BusDeptTimeInfo, BusDeptTimeInfo>(f, t)); } else { // 着検索 -> toの発車時刻がクエリとして与えられた時刻よりも古い tempSource = toStation.Buses.Where(c => c.DayType == daytype && Commons.ConvertToTimeSpan(c.DeptTime) <= baseTime) .Join(fromStation.Buses, t => t.BusId, f => f.BusId, (t, f) => new Tuple<BusDeptTimeInfo, BusDeptTimeInfo>(f, t)); } // 発と着の順番を考慮 var tempRoute = (from busSet in tempSource let bus = instance.Buses[busSet.Item1.BusId] let line = instance.Lines.GetDataFromDayType(daytype)[bus.LineId] where line.Stations.IndexOf(@from) < line.Stations.LastIndexOf(to) select new Tuple<BusDeptTimeInfo,BusDeptTimeInfo,Bus,Line>(busSet.Item1,busSet.Item2, bus, line)); // -> 最初から見つかったもの と 最後に見つかったものを比較すれば、最低でも行けることは保証(最短かどうかは除いて) *1 // 提案コスト検索 IEnumerable<Route> tempResult = null; if (method == RouteSeachMethod.DepartureBase) { tempResult = (from route in tempRoute let deptTime = Commons.ConvertToTimeSpan(route.Item1.DeptTime) let arrTime = Commons.ConvertToTimeSpan(route.Item2.DeptTime) where deptTime <= arrTime // *1の個所では最初と最後をとったが、このDeptInfoが必ず順序が保証されているとは限らない(*1は路線情報で判断) let costTime = Commons.DiffTimespan(deptTime, arrTime) orderby costTime descending // 2番目のクエリ:所要時間 (3番目のクエリ:TransferCount) orderby deptTime ascending // 1番目のクエリ:到着時間が近い順 let costTimeStr = Commons.ConvertToString(costTime) select new Route() { Pathes = new List<Path>() { new Path() { DeptNode = new Node() { Station = result.FromStation, Time = route.Item1.DeptTime }, ArrNode = new Node() { Station = result.ToStation, Time = route.Item2.DeptTime }, Method = TransferMethod.Bus, Line = new LineNameInfo() { Id = route.Item3.LineId, Name = route.Item4.Name, Number = route.Item4.Number }, BusId = route.Item1.BusId, Time = costTimeStr } }, Rank = 1.0, TotalDeptTime = route.Item1.DeptTime, TotalArrTime = route.Item2.DeptTime, TransferCount = 0, TotalTime = costTimeStr }).Select((n, ind) => { n.Rank = ind; return n; }); } else { tempResult = (from route in tempRoute let deptTime = Commons.ConvertToTimeSpan(route.Item1.DeptTime) let arrTime = Commons.ConvertToTimeSpan(route.Item2.DeptTime) where deptTime <= arrTime // *1の個所では最初と最後をとったが、このDeptInfoが必ず順序が保証されているとは限らない(*1は路線情報で判断) let costTime = Commons.DiffTimespan(deptTime, arrTime) orderby costTime descending // 2番目のクエリ:所要時間 (3番目のクエリ:TransferCount) orderby deptTime descending // 1番目のクエリ:到着時間が近い順 let costTimeStr = Commons.ConvertToString(costTime) select new Route() { Pathes = new List<Path>() { new Path() { DeptNode = new Node() { Station = result.FromStation, Time = route.Item1.DeptTime }, ArrNode = new Node() { Station = result.ToStation, Time = route.Item2.DeptTime }, Method = TransferMethod.Bus, Line = new LineNameInfo() { Id = route.Item3.LineId, Name = route.Item4.Name, Number = route.Item4.Number }, BusId = route.Item1.BusId, Time = costTimeStr } }, Rank = 1.0, TotalDeptTime = route.Item1.DeptTime, TotalArrTime = route.Item2.DeptTime, TransferCount = 0, TotalTime = costTimeStr }).Select((n, ind) => { n.Rank = ind; return n; }); } if (count == -1 || count <= 0) { result.Routes = tempResult.ToList(); } else { result.Routes = tempResult.Take(count).ToList(); } return result; }
private async void DriveRouteSearchTest(string cityCode, string searchName, string searchEndName) { POISearchOption pst = new POISearchOption(); pst.SearchName = searchName; pst.CityCode = cityCode; POISearchOption ped = new POISearchOption(); ped.SearchName = searchEndName; ped.CityCode = cityCode; POISearchResult iopStart = await POISearch.PoiSearchWithOption(pst); //查起点坐标 POISearchResult iopEnd = await POISearch.PoiSearchWithOption(ped); //查终点坐标 if (iopStart.Erro != null || iopStart.POIs == null) { MessageDialog msd = new MessageDialog(iopStart.Erro.Message); this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { msd.ShowAsync(); }); return; } if (iopEnd.Erro != null || iopEnd.POIs == null) { MessageDialog msd = new MessageDialog(iopStart.Erro.Message); this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { msd.ShowAsync(); }); return; } POI poist = Enumerable.First <POI>(iopStart.POIs); POI poied = Enumerable.First <POI>(iopEnd.POIs); RouteSearchOption rgo = new RouteSearchOption(); rgo.X1 = poist.X; rgo.Y1 = poist.Y; rgo.X2 = poied.X; rgo.Y2 = poied.Y; RouteSearchResult rgcs = await RouteSearch.RouteSearchWithOption(rgo); if (rgcs.Erro != null) { MessageDialog msd = new MessageDialog("查询公交失败!" + rgcs.Erro.Message, "提示"); this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { msd.ShowAsync(); }); return; } else { this.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { ALngLat lnglatst = new ALngLat(poist.X, poist.Y); AMarker poiMarkerst = new AMarker(); poiMarkerst.IconURI = new Uri("/Samples/qd.png", UriKind.Relative); poiMarkerst.LngLat = lnglatst; ATip tipst = new ATip(); tipst.Title = poist.Name; tipst.ContentText = poist.Address; poiMarkerst.TipFrameworkElement = tipst; map.Children.Add(poiMarkerst); ALngLat lnglated = new ALngLat(poied.X, poied.Y); AMarker poiMarkered = new AMarker(); poiMarkered.IconURI = new Uri("/Samples/zd.png", UriKind.Relative); poiMarkered.LngLat = lnglated; ATip tiped = new ATip(); tiped.Title = poied.Name; tiped.ContentText = poied.Address; poiMarkered.TipFrameworkElement = tiped; map.Children.Add(poiMarkered); APolyline pol = new APolyline(); pol.LineThickness = 5; ObservableCollection <ALngLat> lnglatRoute = new ObservableCollection <ALngLat>(); //线路坐标 IEnumerable <String> lnglatstring; IEnumerable <RouteSegment> rsegment = rgcs.Segment; foreach (RouteSegment rs in rsegment) { lnglatstring = rs.Coor.Split(new Char[] { ';' }); foreach (String ss in lnglatstring) { String[] lnglatds = ss.Split(new Char[] { ',' }); lnglatRoute.Add(new ALngLat(Double.Parse(lnglatds[0]), Double.Parse(lnglatds[1]))); } } pol.LngLats = lnglatRoute; markLayer.Children.Add(pol); map.SetOverlaysFitView(); }); } }