/// <summary> /// 查询通道分钟流量状态 /// </summary> /// <param name="channelId">通道编号</param> /// <returns>通道流量状态</returns> public ChannelMinuteFlow QueryChannelMuniteStatus(string channelId) { channelId = Uri.UnescapeDataString(channelId); ChannelMinuteFlow channelMinuteFlow = new ChannelMinuteFlow { LanesFlow = new List <LaneFlow>() }; FlowChannel channel = _memoryCache.GetChannel(channelId); if (channel != null) { if (channel.SectionId.HasValue) { SectionFlow sectionFlow = _memoryCache.GetSectionLastFlow(channel.SectionId.Value); if (sectionFlow == null) { channelMinuteFlow.SectionFlow = new SectionFlow { SectionId = channel.SectionId.Value, SectionName = channel.RoadSection.SectionName }; } else { _memoryCache.FillSectionFlowCache(sectionFlow); channelMinuteFlow.SectionFlow = sectionFlow; } } foreach (Lane lane in channel.Lanes) { LaneFlow f = _memoryCache.GetLaneLastFlow(lane.DataId); if (f == null) { channelMinuteFlow.LanesFlow.Add(new LaneFlow { DataId = lane.DataId, LaneName = lane.LaneName }); } else { _memoryCache.FillLaneFlow(f); channelMinuteFlow.LanesFlow.Add(f); } } } return(channelMinuteFlow); }
/// <summary> /// 接收到流量数据事件函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FlowReceivedHandler(object sender, WebSocketReceivedEventArges e) { string json = Encoding.UTF8.GetString(e.Packet.ToArray()); if (_clients.TryGetValue(e.Uri.Authority, out Item item)) { try { var v = JsonConvert.DeserializeObject <FlowAdapterData>(json); foreach (LaneAdapterData laneData in v.Data) { LaneFlow laneFlow = new LaneFlow { DataId = $"{laneData.ChannelId}_{laneData.LaneId}", DateTime = laneData.DateTime, Bikes = laneData.Bikes, Tricycles = laneData.Tricycles, Persons = laneData.Persons, Cars = laneData.Cars, Motorcycles = laneData.Motorcycles, Buss = laneData.Buss, Trucks = laneData.Trucks, Vans = laneData.Vans, AverageSpeedData = laneData.AverageSpeed, HeadDistance = laneData.HeadDistance, TimeOccupancy = laneData.TimeOccupancy, Occupancy = laneData.Occupancy, TrafficStatus = laneData.TrafficStatus, Count = 1 }; item.FlowSuccess += 1; _flowBranchBlock.Post(laneFlow); } } catch (Exception ex) { item.FlowFailed += 1; _logger.LogError((int)LogEvent.数据适配, ex, "流量数据解析异常"); } } else { _logger.LogWarning((int)LogEvent.数据适配, $"未知的数据项 {e.Uri.Authority}"); } }
/// <summary> /// 初始化数据库 /// </summary> private async void InitDb() { _logger.LogInformation((int)LogEvent.系统, "初始化数据库"); DateTime minTime = TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel); using (IServiceScope serviceScope = _serviceProvider.CreateScope()) { using (FlowContext context = serviceScope.ServiceProvider.GetRequiredService <FlowContext>()) { if (context.Database.EnsureCreated()) { #region 用户 _logger.LogInformation((int)LogEvent.系统, "创建管理员用户"); UserManager <IdentityUser> userManager = serviceScope.ServiceProvider.GetRequiredService <UserManager <IdentityUser> >(); await userManager.CreateAsync(new IdentityUser("admin"), "123456"); #endregion #region 权限 _logger.LogInformation((int)LogEvent.系统, "创建权限"); IdentityUser adminUser = await userManager.FindByNameAsync("admin"); List <YumekoJabami.Models.Claim> claims = new List <YumekoJabami.Models.Claim> { new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02000000", Descirption = "智慧交通视频检测系统" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010000", Descirption = "设备管理" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010100", Descirption = "设备信息维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010200", Descirption = "设备位置维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010300", Descirption = "国标网关设置" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010400", Descirption = "校时配置" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010500", Descirption = "设备操作" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010600", Descirption = "设备运行状态" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010700", Descirption = "视频信息维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02010800", Descirption = "视频位置维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020000", Descirption = "数据分析" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020100", Descirption = "通行信息查询" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020200", Descirption = "流量数据分析" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020300", Descirption = "IO数据监测" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020400", Descirption = "流量分布查询" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020500", Descirption = "拥堵趋势分析" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020600", Descirption = "状态时间统计" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02020700", Descirption = "交通状态分析" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030000", Descirption = "系统设置" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030100", Descirption = "路口维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030200", Descirption = "路段维护" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030300", Descirption = "用户管理" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030400", Descirption = "角色管理" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030600", Descirption = "字典管理" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030700", Descirption = "参数管理" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030800", Descirption = "日志查询" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02030900", Descirption = "系统监控" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02040000", Descirption = "状况监测" }, new YumekoJabami.Models.Claim { Type = ClaimTypes.Webpage, Value = "02040100", Descirption = "应用检测" }, }; context.TrafficClaims.AddRange(claims); foreach (YumekoJabami.Models.Claim claim in claims) { await userManager.AddClaimAsync(adminUser, new System.Security.Claims.Claim(claim.Type, claim.Value)); } #endregion #region 字典 _logger.LogInformation((int)LogEvent.系统, "创建字典"); List <Code> flowCodes = new List <Code>(); flowCodes.AddRange(Enum.GetValues(typeof(LogEvent)) .Cast <LogEvent>() .Select(e => new Code { Key = typeof(LogEvent).Name, Value = (int)e, Description = e.ToString() })); flowCodes.Add(new Code { Key = "LogLevel", Value = (int)LogLevel.Debug, Description = "调试" }); flowCodes.Add(new Code { Key = "LogLevel", Value = (int)LogLevel.Information, Description = "消息" }); flowCodes.Add(new Code { Key = "LogLevel", Value = (int)LogLevel.Warning, Description = "警告" }); flowCodes.Add(new Code { Key = "LogLevel", Value = (int)LogLevel.Error, Description = "错误" }); flowCodes.AddRange(Enum.GetValues(typeof(ChannelType)) .Cast <ChannelType>() .Select(e => new Code { Key = typeof(ChannelType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(DeviceModel)) .Cast <DeviceModel>() .Select(e => new Code { Key = typeof(DeviceModel).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(DeviceStatus)) .Cast <DeviceStatus>() .Select(e => new Code { Key = typeof(DeviceStatus).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(RtspProtocol)) .Cast <RtspProtocol>() .Select(e => new Code { Key = typeof(RtspProtocol).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(SectionDirection)) .Cast <SectionDirection>() .Select(e => new Code { Key = typeof(SectionDirection).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(SectionType)) .Cast <SectionType>() .Select(e => new Code { Key = typeof(SectionType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(Age)) .Cast <Age>() .Select(e => new Code { Key = typeof(Age).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(NonVehicle)) .Cast <NonVehicle>() .Select(e => new Code { Key = typeof(NonVehicle).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(CarColor)) .Cast <CarColor>() .Select(e => new Code { Key = typeof(CarColor).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(CarType)) .Cast <CarType>() .Select(e => new Code { Key = typeof(CarType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(FlowDirection)) .Cast <FlowDirection>() .Select(e => new Code { Key = typeof(FlowDirection).Name, Value = (int)e, Description = e.ToString() })); flowCodes.Add(new Code { Key = "VehicleType", Value = (int)FlowType.轮车, Description = FlowType.轮车.ToString() }); flowCodes.Add(new Code { Key = "VehicleType", Value = (int)FlowType.卡车, Description = FlowType.卡车.ToString() }); flowCodes.Add(new Code { Key = "VehicleType", Value = (int)FlowType.客车, Description = FlowType.客车.ToString() }); flowCodes.Add(new Code { Key = "VehicleType", Value = (int)FlowType.轿车, Description = FlowType.轿车.ToString() }); flowCodes.Add(new Code { Key = "VehicleType", Value = (int)FlowType.面包车, Description = FlowType.面包车.ToString() }); flowCodes.Add(new Code { Key = "BikeType", Value = (int)FlowType.自行车, Description = FlowType.自行车.ToString() }); flowCodes.Add(new Code { Key = "BikeType", Value = (int)FlowType.摩托车, Description = FlowType.摩托车.ToString() }); flowCodes.Add(new Code { Key = "PedestrainType", Value = (int)FlowType.行人, Description = FlowType.行人.ToString() }); flowCodes.Add(new Code { Key = "FlowType", Value = (int)FlowType.平均速度, Description = FlowType.平均速度.ToString() }); flowCodes.Add(new Code { Key = "FlowType", Value = (int)FlowType.车头时距, Description = FlowType.车头时距.ToString() }); flowCodes.Add(new Code { Key = "FlowType", Value = (int)FlowType.车头间距, Description = FlowType.车头间距.ToString() }); flowCodes.Add(new Code { Key = "FlowType", Value = (int)FlowType.时间占有率, Description = FlowType.时间占有率.ToString() }); flowCodes.Add(new Code { Key = "FlowType", Value = (int)FlowType.空间占有率, Description = FlowType.空间占有率.ToString() }); flowCodes.AddRange(Enum.GetValues(typeof(LaneDirection)) .Cast <LaneDirection>() .Select(e => new Code { Key = typeof(LaneDirection).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(LaneType)) .Cast <LaneType>() .Select(e => new Code { Key = typeof(LaneType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(PlateType)) .Cast <PlateType>() .Select(e => new Code { Key = typeof(PlateType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(Sex)) .Cast <Sex>() .Select(e => new Code { Key = typeof(Sex).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(TrafficStatus)) .Cast <TrafficStatus>() .Select(e => new Code { Key = typeof(TrafficStatus).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(UpperColor)) .Cast <UpperColor>() .Select(e => new Code { Key = typeof(UpperColor).Name, Value = (int)e, Description = e.ToString() })); flowCodes.AddRange(Enum.GetValues(typeof(VideoStructType)) .Cast <VideoStructType>() .Select(e => new Code { Key = typeof(VideoStructType).Name, Value = (int)e, Description = e.ToString() })); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.Minute, Description = "一分钟" }); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.FiveMinutes, Description = "五分钟" }); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.FifteenMinutes, Description = "十五分钟" }); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.Hour, Description = "小时" }); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.Day, Description = "天" }); flowCodes.Add(new Code { Key = "FlowDateLevel", Value = (int)DateTimeLevel.Month, Description = "月" }); flowCodes.Add(new Code { Key = "CongestionDateLevel", Value = (int)DateTimeLevel.Hour, Description = "小时" }); flowCodes.Add(new Code { Key = "CongestionDateLevel", Value = (int)DateTimeLevel.Day, Description = "天" }); flowCodes.Add(new Code { Key = "CongestionDateLevel", Value = (int)DateTimeLevel.Month, Description = "月" }); flowCodes.Add(new Code { Key = "StatusTimeDateLevel", Value = (int)DateTimeLevel.Hour, Description = "小时" }); flowCodes.Add(new Code { Key = "StatusTimeDateLevel", Value = (int)DateTimeLevel.Day, Description = "天" }); flowCodes.Add(new Code { Key = "StatusTimeDateLevel", Value = (int)DateTimeLevel.Month, Description = "月" }); context.Codes.AddRange(flowCodes); #endregion context.Version.Add(new TrafficVersion { Version = Assembly.GetExecutingAssembly().GetName().Version.ToString() }); context.SaveChanges(); } else { try { LaneFlow laneFlow = context.LaneFlows_One.OrderByDescending(f => f.Id).FirstOrDefault(); if (laneFlow != null && TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, laneFlow.DateTime) != minTime) { context.ChangeDatabase(BranchDbConvert.GetTableName(laneFlow.DateTime)); } VideoVehicle vehicle = context.Vehicles.OrderByDescending(v => v.Id).FirstOrDefault(); if (vehicle != null && TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, vehicle.DateTime) != minTime) { context.ChangeVehicleTable(BranchDbConvert.GetTableName(vehicle.DateTime)); } VideoBike bike = context.Bikes.OrderByDescending(v => v.Id).FirstOrDefault(); if (bike != null && TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, bike.DateTime) != minTime) { context.ChangeBikeTable(BranchDbConvert.GetTableName(bike.DateTime)); } VideoPedestrain pedestrain = context.Pedestrains.OrderByDescending(v => v.Id).FirstOrDefault(); if (pedestrain != null && TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, pedestrain.DateTime) != minTime) { context.ChangePedestrainTable(BranchDbConvert.GetTableName(pedestrain.DateTime)); } } catch (MySqlException) { } } } } }
/// <summary> /// 查询通道当天流量状态 /// </summary> /// <param name="channelId">通道编号</param> /// <returns>通道流量状态</returns> public ChannelDayFlow QueryChannelDayStatus(string channelId) { channelId = Uri.UnescapeDataString(channelId); List <Lane> lanes = _memoryCache.GetLanes() .Where(l => l.ChannelId == channelId) .OrderBy(l => l.LaneIndex) .ToList(); HashSet <string> dataIds = lanes.Select(l => l.DataId).ToHashSet(); ChannelDayFlow dayFlow = new ChannelDayFlow { ChannelId = channelId, TodayDayLanes = new List <LaneFlowItem>(), YesterdayDayLanes = new List <LaneFlowItem>(), LastMonthDayLanes = new List <LaneFlowItem>(), LastYearDayLanes = new List <LaneFlowItem>(), TodayDayCharts = new List <List <TrafficChart <DateTime, int, LaneFlow> > >(), YesterdayDayCharts = new List <List <TrafficChart <DateTime, int, LaneFlow> > >(), LastMonthDayCharts = new List <List <TrafficChart <DateTime, int, LaneFlow> > >(), LastYearDayCharts = new List <List <TrafficChart <DateTime, int, LaneFlow> > >() }; DateTime now = DateTime.Now; DateTime today = now.Date; ChannelDayFlow flowCache = _memoryCache.GetChannelDayFlow(channelId, today); if (flowCache == null) { //上月和去年天 var totalDayCharts = _flowManager.QueryCharts(dataIds, DateTimeLevel.Hour , new[] { today.AddMonths(-1), today.AddYears(-1) } , new[] { today.AddMonths(-1).AddDays(1).AddMinutes(-1), today.AddYears(-1).AddDays(1).AddMinutes(-1) } , today); dayFlow.LastMonthDayCharts.Add(totalDayCharts[0]); dayFlow.LastYearDayCharts.Add(totalDayCharts[1]); var totalLastMonthDayList = _flowManager.QueryList(dataIds, DateTimeLevel.Day, today.AddMonths(-1), today.AddMonths(-1).AddDays(1).AddMinutes(-1)); dayFlow.LastMonthDayLanes.Add( totalLastMonthDayList.Count == 0 ? new LaneFlowItem { LaneName = "全部" } : new LaneFlowItem { LaneName = "全部", Total = totalLastMonthDayList[0].Total, Vehicle = totalLastMonthDayList[0].Vehicle, Bike = totalLastMonthDayList[0].Bike, Person = totalLastMonthDayList[0].Persons, Occupancy = totalLastMonthDayList[0].Occupancy / totalLastMonthDayList[0].Count, TimeOccupancy = totalLastMonthDayList[0].TimeOccupancy / totalLastMonthDayList[0].Count }); var totalLastYearDayList = _flowManager.QueryList(dataIds, DateTimeLevel.Day, today.AddYears(-1), today.AddYears(-1).AddDays(1).AddMinutes(-1)); dayFlow.LastYearDayLanes.Add( totalLastYearDayList.Count == 0 ? new LaneFlowItem { LaneName = "全部" } : new LaneFlowItem { LaneName = "全部", Total = totalLastYearDayList[0].Total, Vehicle = totalLastYearDayList[0].Vehicle, Bike = totalLastYearDayList[0].Bike, Person = totalLastYearDayList[0].Persons, Occupancy = totalLastYearDayList[0].Occupancy / totalLastYearDayList[0].Count, TimeOccupancy = totalLastYearDayList[0].TimeOccupancy / totalLastYearDayList[0].Count }); foreach (Lane lane in lanes.OrderBy(l => l.LaneIndex)) { //上月和去年天从数据库查询 var dayCharts = _flowManager.QueryCharts(lane.DataId, DateTimeLevel.Hour , new[] { today.AddMonths(-1), today.AddYears(-1) } , new[] { today.AddMonths(-1).AddDays(1).AddMinutes(-1), today.AddYears(-1).AddDays(1).AddMinutes(-1) } , today); dayFlow.LastMonthDayCharts.Add(dayCharts[0]); dayFlow.LastYearDayCharts.Add(dayCharts[1]); var lastMonthDayList = _flowManager.QueryList(lane.DataId, DateTimeLevel.Day, today.AddMonths(-1), today.AddMonths(-1).AddDays(1).AddMinutes(-1)); dayFlow.LastMonthDayLanes.Add( lastMonthDayList.Count == 0 ? new LaneFlowItem { DataId = lane.DataId, LaneName = lane.LaneName } : new LaneFlowItem { DataId = lane.DataId, LaneName = lane.LaneName, Total = lastMonthDayList[0].Total, Vehicle = lastMonthDayList[0].Vehicle, Bike = lastMonthDayList[0].Bike, Person = lastMonthDayList[0].Persons, Occupancy = lastMonthDayList[0].Occupancy / lastMonthDayList[0].Count, TimeOccupancy = lastMonthDayList[0].TimeOccupancy / lastMonthDayList[0].Count }); var lastYearDayList = _flowManager.QueryList(lane.DataId, DateTimeLevel.Day, today.AddYears(-1), today.AddYears(-1).AddDays(1).AddMinutes(-1)); dayFlow.LastYearDayLanes.Add( lastYearDayList.Count == 0 ? new LaneFlowItem { DataId = lane.DataId, LaneName = lane.LaneName } : new LaneFlowItem { DataId = lane.DataId, LaneName = lane.LaneName, Total = lastYearDayList[0].Total, Vehicle = lastYearDayList[0].Vehicle, Bike = lastYearDayList[0].Bike, Person = lastYearDayList[0].Persons, Occupancy = lastYearDayList[0].Occupancy / lastMonthDayList[0].Count, TimeOccupancy = lastYearDayList[0].TimeOccupancy / lastMonthDayList[0].Count }); } for (int h = 0; h < 24; ++h) { for (int i = 0; i < dataIds.Count + 1; ++i) { if (h > dayFlow.LastMonthDayCharts[i].Count - 1 || dayFlow.LastMonthDayCharts[i][h].Axis != today.AddHours(h)) { dayFlow.LastMonthDayCharts[i].Insert(h, new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Value = 0, Remark = today.AddMonths(-1).AddHours(h).ToString("yyyy-MM-dd HH") }); } if (h > dayFlow.LastYearDayCharts[i].Count - 1 || dayFlow.LastYearDayCharts[i][h].Axis != today.AddHours(h)) { dayFlow.LastYearDayCharts[i].Insert(h, new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Value = 0, Remark = today.AddYears(-1).AddHours(h).ToString("yyyy-MM-dd HH") }); } } } _memoryCache.SetChannelDayFlow(dayFlow, today); } else { dayFlow.LastMonthDayCharts = flowCache.LastMonthDayCharts; dayFlow.LastYearDayCharts = flowCache.LastYearDayCharts; dayFlow.LastMonthDayLanes = flowCache.LastMonthDayLanes; dayFlow.LastYearDayLanes = flowCache.LastYearDayLanes; } for (int i = 0; i < lanes.Count + 1; ++i) { dayFlow.TodayDayCharts.Add(new List <TrafficChart <DateTime, int, LaneFlow> >()); dayFlow.YesterdayDayCharts.Add(new List <TrafficChart <DateTime, int, LaneFlow> >()); dayFlow.TodayDayLanes.Add(new LaneFlowItem()); dayFlow.YesterdayDayLanes.Add(new LaneFlowItem()); } dayFlow.TodayDayLanes[0].LaneName = "全部"; dayFlow.YesterdayDayLanes[0].LaneName = "全部"; for (int h = 0; h <= now.Hour; ++h) { TrafficChart <DateTime, int, LaneFlow> totalChart = new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddHours(h).ToString("yyyy-MM-dd HH") }; dayFlow.TodayDayCharts[0].Add(totalChart); int index = 1; foreach (Lane lane in lanes) { LaneFlow flow = _distributedCache.GetLaneHourFlow(lane.DataId, today.AddHours(h)); if (flow == null) { dayFlow.TodayDayCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddHours(h).ToString("yyyy-MM-dd HH"), Value = 0 }); totalChart.Value += 0; dayFlow.TodayDayLanes[index].DataId = lane.DataId; dayFlow.TodayDayLanes[index].LaneName = lane.LaneName; dayFlow.TodayDayLanes[index].Vehicle += 0; dayFlow.TodayDayLanes[index].Bike += 0; dayFlow.TodayDayLanes[index].Person += 0; dayFlow.TodayDayLanes[index].Total += 0; dayFlow.TodayDayLanes[index].Occupancy += 0; dayFlow.TodayDayLanes[index].TimeOccupancy += 0; dayFlow.TodayDayLanes[index].Count += 0; dayFlow.TodayDayLanes[0].Vehicle += 0; dayFlow.TodayDayLanes[0].Bike += 0; dayFlow.TodayDayLanes[0].Person += 0; dayFlow.TodayDayLanes[0].Total += 0; dayFlow.TodayDayLanes[0].Occupancy += 0; dayFlow.TodayDayLanes[0].TimeOccupancy += 0; dayFlow.TodayDayLanes[0].Count += 0; } else { dayFlow.TodayDayCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddHours(h).ToString("yyyy-MM-dd HH"), Value = flow.Total }); totalChart.Value += flow.Total; dayFlow.TodayDayLanes[index].DataId = lane.DataId; dayFlow.TodayDayLanes[index].LaneName = lane.LaneName; dayFlow.TodayDayLanes[index].Vehicle += flow.Vehicle; dayFlow.TodayDayLanes[index].Bike += flow.Bike; dayFlow.TodayDayLanes[index].Person += flow.Persons; dayFlow.TodayDayLanes[index].Total += flow.Total; dayFlow.TodayDayLanes[index].Occupancy += flow.Occupancy; dayFlow.TodayDayLanes[index].TimeOccupancy += flow.TimeOccupancy; dayFlow.TodayDayLanes[index].Count += flow.Count; dayFlow.TodayDayLanes[0].Vehicle += flow.Vehicle; dayFlow.TodayDayLanes[0].Bike += flow.Bike; dayFlow.TodayDayLanes[0].Person += flow.Persons; dayFlow.TodayDayLanes[0].Total += flow.Total; dayFlow.TodayDayLanes[0].Occupancy += flow.Occupancy; dayFlow.TodayDayLanes[0].TimeOccupancy += flow.TimeOccupancy; dayFlow.TodayDayLanes[0].Count += flow.Count; } index += 1; } } for (int h = 0; h < 24; ++h) { TrafficChart <DateTime, int, LaneFlow> totalChart = new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddDays(-1).AddHours(h).ToString("yyyy-MM-dd HH") }; dayFlow.YesterdayDayCharts[0].Add(totalChart); int index = 1; foreach (Lane lane in lanes) { LaneFlow laneFlow = _distributedCache.GetLaneHourFlow(lane.DataId, today.AddDays(-1).AddHours(h)); if (laneFlow == null) { dayFlow.YesterdayDayCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddDays(-1).AddHours(h).ToString("yyyy-MM-dd HH"), Value = 0 }); totalChart.Value += 0; dayFlow.YesterdayDayLanes[index].DataId = lane.DataId; dayFlow.YesterdayDayLanes[index].LaneName = lane.LaneName; dayFlow.YesterdayDayLanes[index].Vehicle += 0; dayFlow.YesterdayDayLanes[index].Bike += 0; dayFlow.YesterdayDayLanes[index].Person += 0; dayFlow.YesterdayDayLanes[index].Total += 0; dayFlow.YesterdayDayLanes[index].Occupancy += 0; dayFlow.YesterdayDayLanes[index].TimeOccupancy += 0; dayFlow.YesterdayDayLanes[index].Count += 0; dayFlow.YesterdayDayLanes[0].Vehicle += 0; dayFlow.YesterdayDayLanes[0].Bike += 0; dayFlow.YesterdayDayLanes[0].Person += 0; dayFlow.YesterdayDayLanes[0].Total += 0; dayFlow.YesterdayDayLanes[0].Occupancy += 0; dayFlow.YesterdayDayLanes[0].TimeOccupancy += 0; dayFlow.YesterdayDayLanes[0].Count += 0; } else { dayFlow.YesterdayDayCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = today.AddHours(h), Remark = today.AddDays(-1).AddHours(h).ToString("yyyy-MM-dd HH"), Value = laneFlow.Total }); totalChart.Value += laneFlow.Total; dayFlow.YesterdayDayLanes[index].DataId = lane.DataId; dayFlow.YesterdayDayLanes[index].LaneName = lane.LaneName; dayFlow.YesterdayDayLanes[index].Vehicle += laneFlow.Vehicle; dayFlow.YesterdayDayLanes[index].Bike += laneFlow.Bike; dayFlow.YesterdayDayLanes[index].Person += laneFlow.Persons; dayFlow.YesterdayDayLanes[index].Total += laneFlow.Total; dayFlow.YesterdayDayLanes[index].Occupancy += laneFlow.Occupancy; dayFlow.YesterdayDayLanes[index].TimeOccupancy += laneFlow.TimeOccupancy; dayFlow.YesterdayDayLanes[index].Count += laneFlow.Count; dayFlow.YesterdayDayLanes[0].Vehicle += laneFlow.Vehicle; dayFlow.YesterdayDayLanes[0].Bike += laneFlow.Bike; dayFlow.YesterdayDayLanes[0].Person += laneFlow.Persons; dayFlow.YesterdayDayLanes[0].Total += laneFlow.Total; dayFlow.YesterdayDayLanes[0].Occupancy += laneFlow.Occupancy; dayFlow.YesterdayDayLanes[0].TimeOccupancy += laneFlow.TimeOccupancy; dayFlow.YesterdayDayLanes[0].Count += laneFlow.Count; } index += 1; } } for (int i = 0; i < lanes.Count + 1; ++i) { dayFlow.TodayDayLanes[i].Occupancy = dayFlow.TodayDayLanes[i].Count == 0 ? 0 : dayFlow.TodayDayLanes[i].Occupancy / dayFlow.TodayDayLanes[i].Count; dayFlow.YesterdayDayLanes[i].Occupancy = dayFlow.YesterdayDayLanes[i].Count == 0 ? 0 : dayFlow.YesterdayDayLanes[i].Occupancy / dayFlow.YesterdayDayLanes[i].Count; dayFlow.TodayDayLanes[i].TimeOccupancy = dayFlow.TodayDayLanes[i].Count == 0 ? 0 : dayFlow.TodayDayLanes[i].TimeOccupancy / dayFlow.TodayDayLanes[i].Count; dayFlow.YesterdayDayLanes[i].TimeOccupancy = dayFlow.YesterdayDayLanes[i].Count == 0 ? 0 : dayFlow.YesterdayDayLanes[i].TimeOccupancy / dayFlow.YesterdayDayLanes[i].Count; } return(dayFlow); }
/// <summary> /// 查询通道小时流量状态 /// </summary> /// <param name="channelId">通道编号</param> /// <returns>通道流量状态</returns> public ChannelHourFlow QueryChannelHourStatus([FromRoute] string channelId) { channelId = Uri.UnescapeDataString(channelId); List <Lane> lanes = _memoryCache.GetLanes() .Where(l => l.ChannelId == channelId) .OrderBy(l => l.LaneIndex) .ToList(); ChannelHourFlow hourFlow = new ChannelHourFlow { ChannelId = channelId, TodayHourLanes = new List <LaneFlowItem>(), TodayHourCharts = new List <List <TrafficChart <DateTime, int, LaneFlow> > >() }; DateTime now = DateTime.Now; for (int i = 0; i < lanes.Count + 1; ++i) { hourFlow.TodayHourCharts.Add(new List <TrafficChart <DateTime, int, LaneFlow> >()); hourFlow.TodayHourLanes.Add(new LaneFlowItem()); } hourFlow.TodayHourLanes[0].LaneName = "全部"; for (int m = 0; m < 60; ++m) { TrafficChart <DateTime, int, LaneFlow> totalChart = new TrafficChart <DateTime, int, LaneFlow> { Axis = now.AddHours(-1).AddMinutes(m), Remark = now.AddHours(-1).AddMinutes(m).ToString("yyyy-MM-dd HH:mm") }; hourFlow.TodayHourCharts[0].Add(totalChart); int index = 1; foreach (Lane lane in lanes) { LaneFlow laneFlow = _distributedCache.GetLaneMinuteFlow(lane.DataId, now.AddHours(-1).AddMinutes(m)); if (laneFlow == null) { hourFlow.TodayHourCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = now.AddHours(-1).AddMinutes(m), Remark = now.AddHours(-1).AddMinutes(m).ToString("yyyy-MM-dd HH:mm"), Value = 0 }); totalChart.Value += 0; hourFlow.TodayHourLanes[index].DataId = lane.DataId; hourFlow.TodayHourLanes[index].LaneName = lane.LaneName; hourFlow.TodayHourLanes[index].Vehicle += 0; hourFlow.TodayHourLanes[index].Bike += 0; hourFlow.TodayHourLanes[index].Person += 0; hourFlow.TodayHourLanes[index].Total += 0; hourFlow.TodayHourLanes[index].Occupancy += 0; hourFlow.TodayHourLanes[index].TimeOccupancy += 0; hourFlow.TodayHourLanes[index].Count += 0; hourFlow.TodayHourLanes[0].Vehicle += 0; hourFlow.TodayHourLanes[0].Bike += 0; hourFlow.TodayHourLanes[0].Person += 0; hourFlow.TodayHourLanes[0].Total += 0; hourFlow.TodayHourLanes[0].Occupancy += 0; hourFlow.TodayHourLanes[0].TimeOccupancy += 0; hourFlow.TodayHourLanes[0].Count += 0; } else { hourFlow.TodayHourCharts[index].Add(new TrafficChart <DateTime, int, LaneFlow> { Axis = now.AddHours(-1).AddMinutes(m), Remark = now.AddHours(-1).AddMinutes(m).ToString("yyyy-MM-dd HH:mm"), Value = laneFlow.Total }); totalChart.Value += laneFlow.Total; hourFlow.TodayHourLanes[index].DataId = lane.DataId; hourFlow.TodayHourLanes[index].LaneName = lane.LaneName; hourFlow.TodayHourLanes[index].Vehicle += laneFlow.Vehicle; hourFlow.TodayHourLanes[index].Bike += laneFlow.Bike; hourFlow.TodayHourLanes[index].Person += laneFlow.Persons; hourFlow.TodayHourLanes[index].Total += laneFlow.Total; hourFlow.TodayHourLanes[index].Occupancy += laneFlow.Occupancy; hourFlow.TodayHourLanes[index].TimeOccupancy += laneFlow.TimeOccupancy; hourFlow.TodayHourLanes[index].Count += laneFlow.Count; hourFlow.TodayHourLanes[0].Vehicle += laneFlow.Vehicle; hourFlow.TodayHourLanes[0].Bike += laneFlow.Bike; hourFlow.TodayHourLanes[0].Person += laneFlow.Persons; hourFlow.TodayHourLanes[0].Total += laneFlow.Total; hourFlow.TodayHourLanes[0].Occupancy += laneFlow.Occupancy; hourFlow.TodayHourLanes[0].TimeOccupancy += laneFlow.TimeOccupancy; hourFlow.TodayHourLanes[0].Count += 1; } index += 1; } } for (int i = 0; i < lanes.Count + 1; ++i) { hourFlow.TodayHourLanes[i].Occupancy = hourFlow.TodayHourLanes[i].Count == 0 ? 0 : hourFlow.TodayHourLanes[i].Occupancy / hourFlow.TodayHourLanes[i].Count; hourFlow.TodayHourLanes[i].TimeOccupancy = hourFlow.TodayHourLanes[i].Count == 0 ? 0 : hourFlow.TodayHourLanes[i].TimeOccupancy / hourFlow.TodayHourLanes[i].Count; } return(hourFlow); }
public static Dictionary <string, List <LaneFlow> > CreateData(IServiceProvider serviceProvider, List <FlowDevice> devices, List <DataCreateMode> modes, List <DateTime> startTimes, List <DateTime> endTimes, bool initDatabase = false) { if (initDatabase) { ResetDatabase(serviceProvider); } Dictionary <string, List <LaneFlow> > datas = new Dictionary <string, List <LaneFlow> >(); foreach (FlowDevice device in devices) { foreach (var relation in device.FlowDevice_FlowChannels) { foreach (Lane lane in relation.Channel.Lanes) { datas.Add(lane.DataId, new List <LaneFlow>()); } } } for (int i = 0; i < startTimes.Count; ++i) { DateTime minTime = TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, startTimes[i]); DateTime maxTime = TimePointConvert.NextTimePoint(BranchDbConvert.DateLevel, minTime); FlowBranchBlock branch = new FlowBranchBlock(serviceProvider); branch.Open(devices, minTime, maxTime); Random random = new Random(); foreach (FlowDevice device in devices) { foreach (var relation in device.FlowDevice_FlowChannels) { foreach (Lane lane in relation.Channel.Lanes) { int value = 1; for (int m = 0; m < 1440; ++m) { DateTime dataTime = startTimes[i].AddMinutes(m); if (dataTime > DateTime.Now) { break; } if (dataTime >= startTimes[i] && dataTime < endTimes[i]) { LaneFlow laneFlow; if (modes[i] == DataCreateMode.Fixed) { laneFlow = new LaneFlow { DataId = lane.DataId, DateTime = new DateTime(dataTime.Year, dataTime.Month, dataTime.Day, dataTime.Hour, dataTime.Minute, 0), Cars = 1, Buss = 1, Trucks = 1, Vans = 1, Tricycles = 1, Motorcycles = 1, Bikes = 1, Persons = 1, AverageSpeedData = 50, HeadDistance = 10, Occupancy = 30, TimeOccupancy = 40, TrafficStatus = TrafficStatus.轻度拥堵, Count = 1 }; } else if (modes[i] == DataCreateMode.Sequence) { laneFlow = new LaneFlow { DataId = lane.DataId, DateTime = new DateTime(dataTime.Year, dataTime.Month, dataTime.Day, dataTime.Hour, dataTime.Minute, 0), Cars = value++, Buss = 2, Trucks = 3, Vans = 4, Tricycles = 5, Motorcycles = 6, Bikes = 7, Persons = 8, AverageSpeedData = 9, HeadDistance = 10, Occupancy = 12, TimeOccupancy = 13, TrafficStatus = TrafficStatus.通畅, Count = 1 }; } else { laneFlow = new LaneFlow { DataId = lane.DataId, DateTime = new DateTime(dataTime.Year, dataTime.Month, dataTime.Day, dataTime.Hour, dataTime.Minute, 0), Cars = random.Next(1, 10), Buss = random.Next(1, 10), Trucks = random.Next(1, 10), Vans = random.Next(1, 10), Tricycles = random.Next(1, 10), Motorcycles = random.Next(1, 10), Bikes = random.Next(1, 10), Persons = random.Next(1, 10), AverageSpeedData = random.Next(1, 10), HeadDistance = random.Next(1, 10), Occupancy = random.Next(1, 10), TimeOccupancy = random.Next(1, 10), TrafficStatus = (TrafficStatus)random.Next(1, 6), Count = 1 }; } laneFlow.SectionId = lane.Channel.RoadSection.SectionId; laneFlow.SectionType = lane.Channel.RoadSection.SectionType; laneFlow.SectionLength = lane.Channel.RoadSection.Length; laneFlow.FreeSpeed = lane.Channel.RoadSection.FreeSpeed; laneFlow.Distance = laneFlow.Vehicle * lane.Length; laneFlow.TravelTime = laneFlow.AverageSpeedData > 0 ? laneFlow.Vehicle * lane.Length / Convert.ToDouble(laneFlow.AverageSpeedData * 1000 / 3600) : 0; datas[lane.DataId].Add(laneFlow); branch.Post(laneFlow); } ++value; } } } } branch.Close(); if (i == startTimes.Count - 1) { DateTime currentTime = TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel); if (minTime != currentTime) { using (FlowContext context = serviceProvider.GetRequiredService <FlowContext>()) { context.ChangeDatabase(BranchDbConvert.GetTableName(minTime)); } branch.SwitchBranch(maxTime, TimePointConvert.NextTimePoint(BranchDbConvert.DateLevel, maxTime)); } } else { DateTime nextItem = TimePointConvert.CurrentTimePoint(BranchDbConvert.DateLevel, startTimes[i + 1]); if (minTime != nextItem) { using (FlowContext context = serviceProvider.GetRequiredService <FlowContext>()) { context.ChangeDatabase(BranchDbConvert.GetTableName(minTime)); } branch.SwitchBranch(maxTime, TimePointConvert.NextTimePoint(BranchDbConvert.DateLevel, maxTime)); } } } return(datas); }
/// <summary> /// 计算路段当天流量 /// </summary> private void CalculateSectionDayFlow() { DateTime now = DateTime.Now; CityStatus cityStatus = new CityStatus { CongestionDatas = new Dictionary <int, double>(), SectionStatuses = Enum.GetValues(typeof(TrafficStatus)) .Cast <TrafficStatus>() .ToDictionary(trafficStatus => (int)trafficStatus, trafficStatus => new SectionsSpeed()) }; List <RoadSection> sections = _memoryCache.GetSections(); //计算当前分钟路段交通状态 Dictionary <TrafficStatus, List <SectionFlow> > trafficStatusFlows = Enum.GetValues(typeof(TrafficStatus)).Cast <TrafficStatus>().ToDictionary(trafficStatus => trafficStatus, trafficStatus => new List <SectionFlow>()); foreach (var section in sections) { SectionFlow flow = _memoryCache.GetSectionLastFlow(section.SectionId); if (flow != null) { trafficStatusFlows[flow.TrafficStatus].Add(flow); } } foreach (var pair in trafficStatusFlows) { //状态下路网总vkt double totalStatusVkts = pair.Value.Sum(f => f.Vkt); //状态下路网平均速度 double totalStatusAverageSpeed = 0.0; if (totalStatusVkts > 0) { //状态下路网平均速度 totalStatusAverageSpeed = (pair.Value.Sum(f => f.Fls) > 0 ? pair.Value.Sum(f => f.Vkt) / pair.Value.Sum(f => f.Fls) * (pair.Value.Sum(f => f.Vkt) / totalStatusVkts) : 0) * 3600 / 1000; } //当前交通状态 cityStatus.SectionStatuses[(int)pair.Key].AverageSpeed = Convert.ToInt32(totalStatusAverageSpeed); cityStatus.SectionStatuses[(int)pair.Key].SectionCount = pair.Value.Count; } //城市小时拥堵指数 DateTime today = now.Date; for (int h = 0; h < now.Hour; ++h) { double?congestionData = _memoryCache.GetCityHourCongestionData(today.AddHours(h)); if (!congestionData.HasValue) { congestionData = GetHourCongestionData(today.AddHours(h)); _memoryCache.SetCityHourCongestionData(today.AddHours(h), congestionData.Value); } cityStatus.CongestionDatas.Add(h, Math.Round(congestionData.Value, 1)); } cityStatus.CongestionDatas.Add(now.Hour, Math.Round(GetHourCongestionData(today.AddHours(now.Hour)), 1)); //今日总流量 foreach (var lane in _memoryCache.GetLanes()) { LaneFlow flow = _distributedCache.GetLaneDayFlow(lane.DataId, today); if (flow != null) { cityStatus.TotalFlow += flow.Total; } } //今日平均速度 Dictionary <int, List <SectionFlow> > sectionTypeDayFlows = Enum.GetValues(typeof(SectionType)).Cast <SectionType>().ToDictionary(s => (int)s, s => new List <SectionFlow>()); foreach (var section in sections) { SectionFlow flow = _distributedCache.GetSectionDayFlow(section.SectionId, today); if (flow != null) { _memoryCache.FillSectionFlowCache(flow); sectionTypeDayFlows[flow.SectionType].Add(flow); } } //路网总vkt double totalVkts = sectionTypeDayFlows.Sum(p => p.Value.Sum(f => f.Vkt)); if (totalVkts > 0) { cityStatus.AverageSpeed = Convert.ToInt64( sectionTypeDayFlows .Sum(p => p.Value.Sum(f => f.Fls) > 0 ? p.Value.Sum(f => f.Vkt) / p.Value.Sum(f => f.Fls) * (p.Value.Sum(f => f.Vkt) / totalVkts) : 0) * 3600 / 1000); } else { cityStatus.AverageSpeed = 0; } //拥堵排名 cityStatus.SectionCongestionRank = sectionTypeDayFlows .SelectMany(p => p.Value) .Where(f => f.CongestionSpan > 0) .OrderByDescending(f => f.CongestionSpan) .Take(10) .ToList(); //当前拥堵路段列表 cityStatus.SectionCongestions = sectionTypeDayFlows .SelectMany(p => p.Value) .Where(f => f.TrafficStatus >= TrafficStatus.轻度拥堵) .OrderByDescending(f => f.CongestionStartTime) .ToList(); Status = cityStatus; }
/// <summary> /// 计算所有路段分钟流量 /// </summary> /// <param name="time"></param> private void CalculateSectionMinuteFlow(DateTime time) { var totalLanes = _memoryCache.GetLanes(); time = time.Add(-_span); foreach (RoadSection section in _memoryCache.GetSections()) { List <Lane> sectionLanes = totalLanes .Where(l => l.Channel.SectionId.HasValue && l.Channel.SectionId.Value == section.SectionId) .ToList(); SectionFlow sectionFlow = new SectionFlow { SectionId = section.SectionId, DateTime = time, SectionType = section.SectionType, FreeSpeed = section.FreeSpeed, Length = section.Length }; int availableLanesCount = 0; foreach (var lane in sectionLanes) { LaneFlow laneFlow = _distributedCache.GetLaneMinuteFlow(lane.DataId, time); if (laneFlow != null) { sectionFlow.Total += laneFlow.Total; sectionFlow.Vehicle += laneFlow.Vehicle; sectionFlow.HeadDistance += laneFlow.HeadDistance; sectionFlow.TimeOccupancy += laneFlow.TimeOccupancy; sectionFlow.Occupancy += laneFlow.Occupancy; sectionFlow.Distance += laneFlow.Distance; sectionFlow.TravelTime += laneFlow.TravelTime; availableLanesCount += 1; } } if (availableLanesCount > 0) { //路段平均速度(千米/小时) double sectionAverageSpeed = sectionFlow.TravelTime > 0 ? (sectionFlow.Distance / sectionFlow.TravelTime * 3600 / 1000) : 0; //路段行程时间(秒) double sectionTravelTime = sectionAverageSpeed > 0 ? sectionFlow.Length / (sectionAverageSpeed * 1000 / 3600) : 0; //路段自由流行程时间(秒) double sectionFreeTravelTime = sectionFlow.FreeSpeed > 0 ? sectionFlow.Length / (sectionFlow.FreeSpeed * 1000 / 3600) : 0; //路段行程时间比 double sectionTravelTimeProportion = sectionTravelTime < sectionFreeTravelTime ? 1 : sectionTravelTime / sectionFreeTravelTime; //路段交通状态 TrafficStatus trafficStatus; if (sectionAverageSpeed > sectionFlow.FreeSpeed * 0.7) { trafficStatus = TrafficStatus.通畅; } else if (sectionAverageSpeed <= sectionFlow.FreeSpeed * 0.7 && sectionAverageSpeed > sectionFlow.FreeSpeed * 0.5) { trafficStatus = TrafficStatus.基本通畅; } else if (sectionAverageSpeed <= sectionFlow.FreeSpeed * 0.5 && sectionAverageSpeed > sectionFlow.FreeSpeed * 0.4) { trafficStatus = TrafficStatus.轻度拥堵; } else if (sectionAverageSpeed <= sectionFlow.FreeSpeed * 0.4 && sectionAverageSpeed > sectionFlow.FreeSpeed * 0.3) { trafficStatus = TrafficStatus.中度拥堵; } else { trafficStatus = TrafficStatus.严重拥堵; } sectionFlow.Count = 1; sectionFlow.AverageSpeed = sectionAverageSpeed; sectionFlow.HeadDistance = sectionFlow.HeadDistance / availableLanesCount; sectionFlow.Occupancy = sectionFlow.Occupancy / availableLanesCount; sectionFlow.TimeOccupancy = sectionFlow.TimeOccupancy / availableLanesCount; sectionFlow.TrafficStatus = trafficStatus; sectionFlow.Total = sectionFlow.Total; sectionFlow.Vehicle = sectionFlow.Vehicle; sectionFlow.Vkt = sectionFlow.Vehicle * sectionFlow.Length; sectionFlow.Fls = sectionFlow.Vehicle * sectionTravelTime; sectionFlow.TravelTimeProportion = sectionTravelTimeProportion; CaculateSectionHourStatus(sectionFlow); SaveSectionMinuteFlow(sectionFlow); _logger.LogDebug((int)LogEvent.路段流量, $"路段流量 id:{sectionFlow.SectionId} time:{sectionFlow.DateTime} total lanes:{sectionLanes.Count} available lanes:{availableLanesCount} type:{sectionFlow.SectionType} length:{sectionFlow.Length} free speed:{sectionFlow.FreeSpeed} average speed:{sectionFlow.AverageSpeed} head distance:{sectionFlow.HeadDistance} occ:{sectionFlow.Occupancy} tocc {sectionFlow.TimeOccupancy} status:{sectionFlow.TrafficStatus} total:{sectionFlow.Total} vehicle:{sectionFlow.Vehicle} vkt:{sectionFlow.Vkt} fls:{sectionFlow.Fls} ttp:{sectionFlow.TravelTimeProportion}"); } else { _logger.LogDebug((int)LogEvent.路段流量, $"路段流量计算失败 id:{sectionFlow.SectionId} time:{sectionFlow.DateTime} total lanes:{sectionLanes.Count} available lanes:{availableLanesCount}"); } } }
public void TestFlowTimeSpanBlock(int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) { DateTime startDate = new DateTime(startYear, startMonth, startDay); DateTime endDate = new DateTime(endYear, endMonth, endDay); int days = Convert.ToInt32((endDate - startDate).TotalDays + 1); LaneFlowTimeSpanBlock oneMinuteBlock = new LaneFlowTimeSpanBlock(DateTimeLevel.Minute, TestInit.ServiceProvider); BufferBlock <LaneFlow> oneMinuteResult = new BufferBlock <LaneFlow>(); oneMinuteBlock.LinkTo(oneMinuteResult); LaneFlowTimeSpanBlock fiveMinuteBlock = new LaneFlowTimeSpanBlock(DateTimeLevel.FiveMinutes, TestInit.ServiceProvider); BufferBlock <LaneFlow> fiveMinuteResult = new BufferBlock <LaneFlow>(); fiveMinuteBlock.LinkTo(fiveMinuteResult); LaneFlowTimeSpanBlock fifteenMinuteBlock = new LaneFlowTimeSpanBlock(DateTimeLevel.FifteenMinutes, TestInit.ServiceProvider); BufferBlock <LaneFlow> fifteenMinuteResult = new BufferBlock <LaneFlow>(); fifteenMinuteBlock.LinkTo(fifteenMinuteResult); LaneFlowTimeSpanBlock sixtyMinuteBlock = new LaneFlowTimeSpanBlock(DateTimeLevel.Hour, TestInit.ServiceProvider); BufferBlock <LaneFlow> sixtyMinuteResult = new BufferBlock <LaneFlow>(); sixtyMinuteBlock.LinkTo(sixtyMinuteResult); for (DateTime date = startDate; date <= endDate; date = date.AddDays(1)) { for (int i = 0; i < 24 * 60; ++i) { LaneFlow laneFlow = new LaneFlow { DateTime = date.AddMinutes(i), Cars = 1 }; oneMinuteBlock.InputBlock.Post(laneFlow); fiveMinuteBlock.InputBlock.Post(laneFlow); fifteenMinuteBlock.InputBlock.Post(laneFlow); sixtyMinuteBlock.InputBlock.Post(laneFlow); } } oneMinuteBlock.InputBlock.Complete(); oneMinuteBlock.WaitCompletion(); fiveMinuteBlock.InputBlock.Complete(); fiveMinuteBlock.WaitCompletion(); fifteenMinuteBlock.InputBlock.Complete(); fifteenMinuteBlock.WaitCompletion(); sixtyMinuteBlock.InputBlock.Complete(); sixtyMinuteBlock.WaitCompletion(); oneMinuteResult.TryReceiveAll(out IList <LaneFlow> oneMinuteFlows); Assert.AreEqual(days * 24 * 60, oneMinuteFlows.Count); for (int i = 0; i < oneMinuteFlows.Count; ++i) { Assert.AreEqual(startDate.AddMinutes(i), oneMinuteFlows[i].DateTime); Assert.AreEqual(1, oneMinuteFlows[i].Cars); } fiveMinuteResult.TryReceiveAll(out IList <LaneFlow> fiveFlows); Assert.AreEqual(days * 24 * 60 / 5, fiveFlows.Count); for (int i = 0; i < fiveFlows.Count; ++i) { Assert.AreEqual(startDate.AddMinutes(i * 5), fiveFlows[i].DateTime); Assert.AreEqual(5, fiveFlows[i].Cars); } fifteenMinuteResult.TryReceiveAll(out IList <LaneFlow> fifteenFlows); Assert.AreEqual(days * 24 * 60 / 15, fifteenFlows.Count); for (int i = 0; i < fifteenFlows.Count; ++i) { Assert.AreEqual(startDate.AddMinutes(i * 15), fifteenFlows[i].DateTime); Assert.AreEqual(15, fifteenFlows[i].Cars); } sixtyMinuteResult.TryReceiveAll(out IList <LaneFlow> sixtyFlows); Assert.AreEqual(days * 24, sixtyFlows.Count); for (int i = 0; i < sixtyFlows.Count; ++i) { Assert.AreEqual(startDate.AddHours(i), sixtyFlows[i].DateTime); Assert.AreEqual(60, sixtyFlows[i].Cars); } }