public MeteoReport GetMeteoReportDataGlobally(DateTime from, DateTime to, decimal normTemperature, decimal normPrecipitation) { // getting all stations that are for the selected period var stations = dbContext.Stations.Where(x => x.StationAvailabilityPeriods.Any(period => (period.From <= from && from <= period.To) || (from <= period.From && period.From <= to))); List <int> stationsIds = new List <int>(); var allDaysData = new List <DayWeatherData>(); // get days data for that stations for from/to foreach (var station in stations) { var daysData = dbContext.DaysData .Where(dd => dd.StationId == station.Id) .Where(x => from <= x.Date && x.Date <= to) .ToList(); if (daysData.Count() > 0) { allDaysData.AddRange(daysData); stationsIds.Add(station.Id); } } var groupedStationWeights = dbContext.StationsWeights .Where(x => stationsIds.Any(y => y == x.StationId)) .Where(x => (x.From <= from && from <= x.To) || (from <= x.From && x.From <= to)) .GroupBy(x => x.Station.Name); IDictionary <int, decimal> stationsWeightsTemp = new Dictionary <int, decimal>();// maps station id with weight foreach (var stationId in stationsIds) { stationsWeightsTemp.Add(stationId, 0); } decimal stationsWeightsSum = 0; foreach (var stationWeightGroup in groupedStationWeights) { StationWeight weightToAdd = stationWeightGroup .OrderByDescending(x => x.AddedOn) .FirstOrDefault(); var stationId = stationsWeightsTemp.Keys.Where(x => x == weightToAdd.StationId).FirstOrDefault(); if (stationId > 0) { stationsWeightsTemp[stationId] = weightToAdd.Weight; stationsWeightsSum += weightToAdd.Weight; } } IDictionary <int, decimal> stationsWeights = new Dictionary <int, decimal>(); foreach (var pair in stationsWeightsTemp) { stationsWeights.Add(pair.Key, pair.Value / stationsWeightsSum); } //MeteoReport reportMaxTemperature = reportWeight.Aggregate((agg, next) => next.Key.TemperatureMax > agg.Key.TemperatureMax ? next : agg).Key; //MeteoReport reportMinTemperature = reportWeight.Aggregate((agg, next) => next.Key.TemperatureMin < agg.Key.TemperatureMin ? next : agg).Key); decimal temperatureSum = 0; decimal precipitationSum = 0; decimal reportMaxTemperature = decimal.MinValue; DateTime reportMaxTemperatureDate = DateTime.Now; decimal reportMinTemperature = decimal.MaxValue; DateTime reportMinTemperatureDate = DateTime.Now; decimal reportMaxPrecipitation = decimal.MinValue; DateTime reportMaxPrecipitationDate = DateTime.Now; HashSet <DateTime> dayCountPrecipitationBiggerThan1 = new HashSet <DateTime>(); // contains days in which there is precipitation bigger than 1 HashSet <DateTime> dayCountPrecipitationBiggerThan10 = new HashSet <DateTime>(); // contains days in which there is precipitation bigger than 10 HashSet <DateTime> dayCountWindBiggerThan14 = new HashSet <DateTime>(); // contains days in which there is wind bigger than 14 HashSet <DateTime> dayCountThunders = new HashSet <DateTime>(); // contains days in which there are thunders decimal averageDivider = 0; foreach (var eachDay in allDaysData) { if (eachDay.Temperature > reportMaxTemperature) { reportMaxTemperature = eachDay.Temperature; reportMaxTemperatureDate = eachDay.Date; } if (eachDay.Temperature < reportMinTemperature) { reportMinTemperature = eachDay.Temperature; reportMinTemperatureDate = eachDay.Date; } if (eachDay.Precipitation > reportMaxPrecipitation) { reportMaxPrecipitation = eachDay.Precipitation; reportMaxPrecipitationDate = eachDay.Date; } averageDivider += stationsWeights[eachDay.StationId]; temperatureSum += eachDay.Temperature * stationsWeights[eachDay.StationId]; precipitationSum += eachDay.Precipitation; if (eachDay.Precipitation >= 1) { dayCountPrecipitationBiggerThan1.Add(eachDay.Date); } if (eachDay.Precipitation >= 10) { dayCountPrecipitationBiggerThan10.Add(eachDay.Date); } if (eachDay.Wind >= 14) { dayCountWindBiggerThan14.Add(eachDay.Date); } if (eachDay.ThunderCount > 0) { dayCountThunders.Add(eachDay.Date); } } decimal averageTemperature = temperatureSum / averageDivider; return(new MeteoReport( -1, "Global", averageTemperature, Math.Abs(averageTemperature - normTemperature), reportMaxTemperature, reportMaxTemperatureDate, reportMinTemperature, reportMinTemperatureDate, precipitationSum, Math.Abs(precipitationSum - normPrecipitation), reportMaxPrecipitation, reportMaxPrecipitationDate, dayCountPrecipitationBiggerThan1.Count(), dayCountPrecipitationBiggerThan10.Count(), dayCountWindBiggerThan14.Count(), dayCountThunders.Count() )); }
public MeteoReport GetMeteoReportDataGlobally(DateTime from, DateTime to, decimal normTemperature, decimal normPrecipitation) { ICollection <MeteoReport> reportForStations = GetMeteoReportData(from, to, normTemperature, normPrecipitation); var groupedStationWeights = dbContext.StationsWeights .Where(x => reportForStations.Any(y => y.StationId == x.StationId)) .Where(x => (x.From <= from && from <= x.To) || (from <= x.From && x.From <= to)) .GroupBy(x => x.Station.Name); IDictionary <MeteoReport, decimal> reportWeightTemp = new Dictionary <MeteoReport, decimal>();// maps report with weight foreach (var meteoReport in reportForStations) { reportWeightTemp.Add(meteoReport, 0); //reportWeightTemp[meteoReport] = 0; } decimal reportWeightsSum = 0; foreach (var stationWeightGroup in groupedStationWeights) { StationWeight weightToAdd = stationWeightGroup .OrderByDescending(x => x.AddedOn) .FirstOrDefault(); var report = reportWeightTemp.Keys.Where(x => x.StationId == weightToAdd.StationId).FirstOrDefault(); if (report != null) { reportWeightTemp[report] = weightToAdd.Weight; reportWeightsSum += weightToAdd.Weight; } } IDictionary <MeteoReport, decimal> reportWeight = new Dictionary <MeteoReport, decimal>(); foreach (var pair in reportWeightTemp) { reportWeight.Add(pair.Key, pair.Value / reportWeightsSum); //reportWeight[pair.Key] = pair.Value / reportWeightsSum; } decimal averageTemperature = reportWeight.Sum(x => x.Key.TemperatureAvg * x.Value); //MeteoReport reportMaxTemperature = reportWeight.Aggregate((agg, next) => next.Key.TemperatureMax > agg.Key.TemperatureMax ? next : agg).Key; //MeteoReport reportMinTemperature = reportWeight.Aggregate((agg, next) => next.Key.TemperatureMin < agg.Key.TemperatureMin ? next : agg).Key); decimal reportMaxTemperature = decimal.MinValue; DateTime reportMaxTemperatureDate = DateTime.Now; decimal reportMinTemperature = decimal.MaxValue; DateTime reportMinTemperatureDate = DateTime.Now; decimal reportMaxPrecipitation = decimal.MinValue; DateTime reportMaxPrecipitationDate = DateTime.Now; foreach (var item in reportWeight) { var actualItem = item.Key; if (actualItem.TemperatureMax > reportMaxTemperature) { reportMaxTemperature = actualItem.TemperatureMax; reportMaxTemperatureDate = actualItem.TemperatureMaxDate; } if (actualItem.TemperatureMin < reportMinTemperature) { reportMinTemperature = actualItem.TemperatureMin; reportMinTemperatureDate = actualItem.TemperatureMinDate; } if (actualItem.PrecipitationMax > reportMaxPrecipitation) { reportMaxPrecipitation = actualItem.PrecipitationMax; reportMaxPrecipitationDate = actualItem.PrecipitationMaxDate; } } decimal precipitationSum = reportWeight.Sum(x => x.Key.PrecipitationSum * x.Value); return(new MeteoReport( -1, "Global", averageTemperature, Math.Abs(averageTemperature - normTemperature), reportMaxTemperature, reportMaxTemperatureDate, reportMinTemperature, reportMinTemperatureDate, precipitationSum, Math.Abs(precipitationSum - normPrecipitation), reportMaxPrecipitation, reportMaxPrecipitationDate, reportWeight.Count > 0 ? reportWeight.Max(x => x.Key.DayCountPrecipitationBiggerThan1) : 0, reportWeight.Count > 0 ? reportWeight.Max(x => x.Key.DayCountPrecipitationBiggerThan10) : 0, reportWeight.Count > 0 ? reportWeight.Max(x => x.Key.DayCountWindBiggerThan14) : 0, reportWeight.Count > 0 ? reportWeight.Max(x => x.Key.DayCountThunders) : 0 )); }