Inheritance: BaseModel
        public AirportProfile(
            string name,
            string code,
            string icaocode,
            AirportType type,
            Period<DateTime> period,
            Town town,
            TimeSpan offsetGMT,
            TimeSpan offsetDST,
            Coordinates coordinates,
            GeneralHelpers.Size cargo,
            double cargovolume,
            Weather.Season season)
        {
            PaxValues = new List<PaxValue>();

            Expansions = new List<AirportExpansion>();
            Name = name;
            Period = period;
            IATACode = code;
            ICAOCode = icaocode;
            Type = type;
            Town = town;
            Coordinates = coordinates;
            CargoVolume = cargovolume;
            MajorDestionations = new Dictionary<string, int>();
            Cargo = cargo;
            Logo = "";
            OffsetDST = offsetDST;
            OffsetGMT = offsetGMT;
            Season = season;
            ID =
                $"{char.ConvertToUtf32(IATACode, 0):00}-{char.ConvertToUtf32(IATACode, 1):00}-{char.ConvertToUtf32(IATACode, 2):00}-{name.Length:00}-{char.ConvertToUtf32(Name, Name.Length/2):00}-{(int) Cargo:00}";
        }
 public WeatherAverage(
     int month,
     double temperatureMin,
     double temperatureMax,
     int precipitation,
     Weather.eWindSpeed windspeedMin,
     Weather.eWindSpeed windspeedMax,
     Country country)
     : this(month, temperatureMin, temperatureMax, precipitation, windspeedMin, windspeedMax, country, null, null)
 {
 }
 public HourlyWeather(
     double temperature,
     Weather.CloudCover cover,
     Weather.Precipitation precip,
     Weather.eWindSpeed windspeed,
     Weather.WindDirection direction)
 {
     Temperature = temperature;
     Precip = precip;
     Cover = cover;
     WindSpeed = windspeed;
     Direction = direction;
 }
 public WeatherAverage(
     int month,
     double temperatureMin,
     double temperatureMax,
     int precipitation,
     Weather.eWindSpeed windspeedMin,
     Weather.eWindSpeed windspeedMax,
     Airport airport)
     : this(month,
         temperatureMin,
         temperatureMax,
         precipitation,
         windspeedMin,
         windspeedMax,
         airport.Profile.Town.Country,
         airport.Profile.Town,
         airport)
 {
 }
 public WeatherAverage(
     int month,
     double temperatureMin,
     double temperatureMax,
     int precipitation,
     Weather.eWindSpeed windspeedMin,
     Weather.eWindSpeed windspeedMax,
     Town town)
     : this(month,
         temperatureMin,
         temperatureMax,
         precipitation,
         windspeedMin,
         windspeedMax,
         town.Country,
         town,
         null)
 {
 }
Example #6
0
 public Airport(AirportProfile profile)
 {
     Profile = profile;
     Income = 0;
     DestinationPassengers = new List<DestinationDemand>();
     DestinationCargo = new List<DestinationDemand>();
     _facilities = new List<AirlineAirportFacility>();
     Cooperations = new List<Cooperation>();
     Statistics = new AirportStatistics();
     Weather = new Weather[5];
     Terminals = new Terminals(this);
     Runways = new List<Runway>();
     _hubs = new List<Hub>();
     DestinationPassengerStatistics = new Dictionary<Airport, long>();
     DestinationCargoStatistics = new Dictionary<Airport, double>();
     LastExpansionDate = new DateTime(1900, 1, 1);
     Statics = new AirportStatics(this);
     AirlineContracts = new List<AirportContract>();
 }
 public WeatherAverage(
     int month,
     double temperatureMin,
     double temperatureMax,
     int precipitation,
     Weather.eWindSpeed windspeedMin,
     Weather.eWindSpeed windspeedMax,
     Country country,
     Town town,
     Airport airport)
 {
     Month = month;
     Airport = airport;
     Country = country;
     Town = town;
     TemperatureMin = temperatureMin;
     TemperatureMax = temperatureMax;
     WindSpeedMax = windspeedMax;
     WindSpeedMin = windspeedMin;
     Precipitation = precipitation;
 }
        //returns if the wind is tail (1), head (-1), or from side (0)
        private static int GetWindInfluence(FleetAirliner airliner, Weather currentWeather)
        {
            double direction = MathHelpers.GetDirection(airliner.CurrentFlight.GetDepartureAirport().Profile.Coordinates.ConvertToGeoCoordinate(),
                                                        airliner.CurrentFlight.GetNextDestination().Profile.Coordinates.ConvertToGeoCoordinate());

            Weather.WindDirection windDirection = MathHelpers.GetWindDirectionFromDirection(direction);

            int windDirectionLenght = Enum.GetValues(typeof (Weather.WindDirection)).Length;
            int indexCurrentPosition = Array.IndexOf(Enum.GetValues(typeof (Weather.WindDirection)), windDirection);
            //int indexWeather = Array.IndexOf(Enum.GetValues(typeof(Weather.WindDirection)),currentWeather.WindSpeed);

            //check for tail wind
            Weather.WindDirection windTailLeft = indexCurrentPosition > 0 ? (Weather.WindDirection) indexCurrentPosition - 1 : (Weather.WindDirection) windDirectionLenght - 1;
            Weather.WindDirection windTailRight = indexCurrentPosition < windDirectionLenght - 1 ? (Weather.WindDirection) indexCurrentPosition + 1 : 0;

            if (windTailLeft == currentWeather.Direction || windTailRight == currentWeather.Direction || windDirection == currentWeather.Direction)
                return 1;

            Weather.WindDirection windOpposite = indexCurrentPosition - (windDirectionLenght/2) > 0
                                                     ? (Weather.WindDirection) indexCurrentPosition - (windDirectionLenght/2)
                                                     : (Weather.WindDirection) windDirectionLenght - 1 - indexCurrentPosition - (windDirectionLenght/2);
            int indexOpposite = Array.IndexOf(Enum.GetValues(typeof (Weather.WindDirection)), windOpposite);

            Weather.WindDirection windHeadLeft = indexOpposite > 0 ? (Weather.WindDirection) indexOpposite - 1 : (Weather.WindDirection) windDirectionLenght - 1;
            Weather.WindDirection windHeadRight = indexOpposite < windDirectionLenght - 1 ? (Weather.WindDirection) indexOpposite + 1 : 0;

            if (windHeadLeft == currentWeather.Direction || windHeadRight == currentWeather.Direction || windOpposite == currentWeather.Direction)
                return -1;

            return 0;
        }
        public static bool CanFillRoutesEntries(
            Airport airport,
            Airline airline,
            List<AirportContract> contracts,
            Weather.Season season)
        {
            List<Route> routes = GetAirportRoutes(airport, airline);

            int numberOfOccupiedSlots =
                GetOccupiedSlotTimes(airport, airline, contracts, season)
                    .GroupBy(s => s.Ticks).Count(x => x.Count() > 1);
            return numberOfOccupiedSlots == 0 && !(routes.Count > 0 && contracts.Count == 0);
        }
        private static Weather CreateDayWeather(Airport airport, DateTime date, Weather previousWeather)
        {
            WeatherAverage average = WeatherAverages.GetWeatherAverage(date.Month, airport);

            if (average != null)
            {
                return CreateDayWeather(date, previousWeather, average);
            }

            var precipitationValues = (Weather.Precipitation[]) Enum.GetValues(typeof (Weather.Precipitation));
            var coverValues = (Weather.CloudCover[]) Enum.GetValues(typeof (Weather.CloudCover));
            var windDirectionValues = (Weather.WindDirection[]) Enum.GetValues(typeof (Weather.WindDirection));
            var windSpeedValues = (Weather.eWindSpeed[]) Enum.GetValues(typeof (Weather.eWindSpeed));
            Weather.eWindSpeed windSpeed;
            double temperature;

            Weather.WindDirection windDirection = windDirectionValues[Rnd.Next(windDirectionValues.Length)];

            if (previousWeather == null)
            {
                windSpeed = windSpeedValues[Rnd.Next(windSpeedValues.Length)];

                const double maxTemp = 40;
                const double minTemp = -20;

                temperature = MathHelpers.GetRandomDoubleNumber(minTemp, maxTemp);
            }
            else
            {
                int windIndex = windSpeedValues.ToList().IndexOf(previousWeather.WindSpeed);
                windSpeed =
                    windSpeedValues[
                        Rnd.Next(Math.Max(0, windIndex - 2), Math.Min(windIndex + 2, windSpeedValues.Length))];

                double previousTemperature = (previousWeather.TemperatureHigh + previousWeather.TemperatureLow)/2;

                double maxTemp = Math.Min(40, previousTemperature + 5);
                double minTemp = Math.Max(-20, previousTemperature - 5);

                temperature = MathHelpers.GetRandomDoubleNumber(minTemp, maxTemp);
            }

            double temperatureLow = temperature - Rnd.Next(1, 10);
            double temperatureHigh = temperature + Rnd.Next(1, 10);

            double tempDiff = temperatureHigh - temperatureLow;
            double temperatureSunrise = temperatureLow + MathHelpers.GetRandomDoubleNumber(-2, Math.Min(tempDiff, 2));
            double temperatureSunset = temperatureHigh - MathHelpers.GetRandomDoubleNumber(-2, Math.Min(tempDiff, 2));
            double temperatureDayend = temperatureLow + Rnd.Next(-2, 2);

            Weather.CloudCover cover = coverValues[Rnd.Next(coverValues.Length)];
            Weather.Precipitation precip;
            if (cover == Weather.CloudCover.Overcast)
            {
                precip = precipitationValues[Rnd.Next(precipitationValues.Length)];
            }

            var hourlyTemperature = new HourlyWeather[24];

            if (previousWeather == null)
            {
                hourlyTemperature[0] = new HourlyWeather(
                    temperatureLow,
                    cover,
                    cover == Weather.CloudCover.Overcast ? GetPrecipitation(temperatureLow) : Weather.Precipitation.None,
                    windSpeed,
                    windDirection);
            }
            else
            {
                hourlyTemperature[0] = previousWeather.Temperatures[previousWeather.Temperatures.Length - 1];
            }

            double morningSteps = (temperatureSunrise - hourlyTemperature[0].Temperature)/(Weather.Sunrise - 1);

            for (int i = 1; i <= Weather.Sunrise; i++)
            {
                double temp = hourlyTemperature[i - 1].Temperature + morningSteps;
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }

            double daySteps = (temperatureSunset - temperatureSunrise)/(Weather.Sunset - Weather.Sunrise - 1);

            for (int i = Weather.Sunrise + 1; i < Weather.Sunset; i++)
            {
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                double temp = hourlyTemperature[i - 1].Temperature + daySteps;
                if (hourlyCover != hourlyTemperature[i - 1].Cover && hourlyCover == Weather.CloudCover.Overcast)
                {
                    temp -= MathHelpers.GetRandomDoubleNumber(1, 4);
                }
                if (hourlyCover != hourlyTemperature[i - 1].Cover
                    && hourlyTemperature[i - 1].Cover == Weather.CloudCover.Overcast)
                {
                    temp += MathHelpers.GetRandomDoubleNumber(1, 4);
                }

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }

            double eveningSteps = (temperatureDayend - temperatureSunset)/(hourlyTemperature.Length - Weather.Sunset);

            for (int i = Weather.Sunset; i < hourlyTemperature.Length; i++)
            {
                double temp = hourlyTemperature[i - 1].Temperature + eveningSteps;
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }

            temperatureLow = hourlyTemperature.Min(t => t.Temperature);
            temperatureHigh = hourlyTemperature.Max(t => t.Temperature);
            cover =
                (from c in hourlyTemperature group c by c.Cover into g select new {Cover = g.Key, Qty = g.Count()})
                    .OrderByDescending(g => g.Qty).First().Cover;
            precip =
                (from c in hourlyTemperature group c by c.Precip into g select new {Precip = g.Key, Qty = g.Count()})
                    .OrderByDescending(g => g.Qty).First().Precip;

            var weather = new Weather(
                date,
                windSpeed,
                windDirection,
                cover,
                precip,
                hourlyTemperature,
                temperatureLow,
                temperatureHigh);

            return weather;
        }
 public static List<TimeSpan> GetOccupiedSlotTimes(Airport airport, Airline airline, Weather.Season season, Terminal.TerminalType type)
 {
     return GetOccupiedSlotTimes(
         airport,
         airline,
         airport.AirlineContracts.Where(c => c.Airline == airline && c.TerminalType == type).ToList(),
         season);
 }
        //checks an airport for extending of runway
        //returns all occupied slot times for an airline at an airport (15 minutes slots)
        public static List<TimeSpan> GetOccupiedSlotTimes(
            Airport airport,
            Airline airline,
            List<AirportContract> contracts,
            Weather.Season season)
        {
            var occupiedSlots = new List<KeyValuePair<Route, TimeSpan>>();

            var gateTimeBefore = new TimeSpan(0, 15, 0);
            var gateTimeAfter = new TimeSpan(0, 15, 0);

            int gates = contracts.Sum(c => c.NumberOfGates);

            var routes = new List<Route>(GetAirportRoutes(airport, airline));

            var entries =
                new List<RouteTimeTableEntry>(
                    routes.Where(r => season == Weather.Season.AllYear || season == r.Season)
                          .SelectMany(r => r.TimeTable.Entries));

            foreach (RouteTimeTableEntry entry in entries)
            {
                var entryTakeoffTime = new TimeSpan(
                    (int) entry.Day,
                    entry.Time.Hours,
                    entry.Time.Minutes,
                    entry.Time.Seconds);
                TimeSpan entryLandingTime =
                    entryTakeoffTime.Add(entry.TimeTable.Route.GetFlightTime(entry.Airliner.Airliner.Type));

                if (entryLandingTime.Days > 6)
                {
                    entryLandingTime = new TimeSpan(
                        0,
                        entryLandingTime.Hours,
                        entryLandingTime.Minutes,
                        entryLandingTime.Seconds);
                }

                if (entry.DepartureAirport == airport)
                {
                    TimeSpan entryStartTakeoffTime = entryTakeoffTime.Subtract(gateTimeBefore);
                    TimeSpan entryEndTakeoffTime = entryTakeoffTime.Add(gateTimeAfter);

                    var tTakeoffTime = new TimeSpan(
                        entryStartTakeoffTime.Days,
                        entryStartTakeoffTime.Hours,
                        (entryStartTakeoffTime.Minutes/15)*15,
                        0);

                    while (tTakeoffTime < entryEndTakeoffTime)
                    {
                        if (!occupiedSlots.Exists(s => s.Key == entry.TimeTable.Route && s.Value == tTakeoffTime))
                        {
                            occupiedSlots.Add(new KeyValuePair<Route, TimeSpan>(entry.TimeTable.Route, tTakeoffTime));
                        }
                        tTakeoffTime = tTakeoffTime.Add(new TimeSpan(0, 15, 0));
                    }
                }

                if (entry.DepartureAirport != airport)
                {
                    TimeSpan entryStartLandingTime = entryLandingTime.Subtract(gateTimeBefore);
                    TimeSpan entryEndLandingTime = entryLandingTime.Add(gateTimeAfter);

                    var tLandingTime = new TimeSpan(
                        entryStartLandingTime.Days,
                        entryStartLandingTime.Hours,
                        (entryStartLandingTime.Minutes/15)*15,
                        0);

                    while (tLandingTime < entryEndLandingTime)
                    {
                        if (!occupiedSlots.Exists(s => s.Key == entry.TimeTable.Route && s.Value == tLandingTime))
                        {
                            occupiedSlots.Add(new KeyValuePair<Route, TimeSpan>(entry.TimeTable.Route, tLandingTime));
                        }
                        tLandingTime = tLandingTime.Add(new TimeSpan(0, 15, 0));
                    }
                }
            }

            var slots = (from s in occupiedSlots group s.Value by s.Value into g select new {Time = g.Key, Slots = g});

            return slots.Where(s => s.Slots.Count() >= gates).SelectMany(s => s.Slots).ToList();
        }
        //creates the weather (5 days) for a number of airport with an average
        public static void CreateAirportsWeather(List<Airport> airports, WeatherAverage average)
        {
            if (airports.Count > 0)
            {
                const int maxDays = 5;
                var weathers = new Weather[maxDays];

                if (airports[0].Weather[0] == null)
                {
                    for (int i = 0; i < maxDays; i++)
                    {
                        weathers[i] = CreateDayWeather(
                            GameObject.GetInstance().GameTime.AddDays(i),
                            i > 0 ? weathers[i - 1] : null,
                            average);
                    }
                }
                else
                {
                    for (int i = 1; i < maxDays; i++)
                    {
                        weathers[i - 1] = airports[0].Weather[i];
                    }

                    weathers[maxDays - 1] = CreateDayWeather(
                        GameObject.GetInstance().GameTime.AddDays(maxDays - 1),
                        weathers[maxDays - 2],
                        average);
                }

                foreach (Airport airport in airports)
                {
                    airport.Weather = weathers;
                }
            }
        }
        //creates the weather from an average
        private static Weather CreateDayWeather(DateTime date, Weather previousWeather, WeatherAverage average)
        {
            var windDirectionValues = (Weather.WindDirection[]) Enum.GetValues(typeof (Weather.WindDirection));
            var windSpeedValues = (Weather.eWindSpeed[]) Enum.GetValues(typeof (Weather.eWindSpeed));
            var coverValues = (Weather.CloudCover[]) Enum.GetValues(typeof (Weather.CloudCover));

            Weather.WindDirection windDirection = windDirectionValues[Rnd.Next(windDirectionValues.Length)];
            Weather.CloudCover cover;
            Weather.Precipitation precip;
            Weather.eWindSpeed windSpeed;
            double temperatureLow,
                   temperatureHigh;

            int windIndexMin = windSpeedValues.ToList().IndexOf(average.WindSpeedMin);
            int windIndexMax = windSpeedValues.ToList().IndexOf(average.WindSpeedMax);

            if (previousWeather == null)
            {
                windSpeed = windSpeedValues[Rnd.Next(windIndexMin, windIndexMax)];

                temperatureLow = MathHelpers.GetRandomDoubleNumber(
                    average.TemperatureMin - 5,
                    average.TemperatureMin + 5);
                temperatureHigh =
                    MathHelpers.GetRandomDoubleNumber(
                        Math.Max(average.TemperatureMax - 5, temperatureLow + 1),
                        average.TemperatureMax + 5);
            }
            else
            {
                double previousTemperature = (previousWeather.TemperatureHigh + previousWeather.TemperatureLow)/2;
                int windIndex = windSpeedValues.ToList().IndexOf(previousWeather.WindSpeed);
                windSpeed =
                    windSpeedValues[
                        Rnd.Next(Math.Max(windIndexMin, windIndex - 2), Math.Min(windIndex + 2, windIndexMax))];

                double minTemp = Math.Max(average.TemperatureMin, previousTemperature - 5);
                temperatureLow = MathHelpers.GetRandomDoubleNumber(minTemp - 5, minTemp + 5);

                double maxTemp = Math.Min(average.TemperatureMax, previousTemperature + 5);

                temperatureHigh = MathHelpers.GetRandomDoubleNumber(Math.Max(maxTemp - 5, temperatureLow), maxTemp + 5);
                //rnd.NextDouble() * ((maxTemp + 5) - Math.Max(maxTemp - 5, temperatureLow + 2)) + Math.Max(maxTemp - 5, temperatureLow + 2);
            }

            double tempDiff = temperatureHigh - temperatureLow;
            double temperatureSunrise = temperatureLow + MathHelpers.GetRandomDoubleNumber(-2, Math.Min(tempDiff, 2));
            double temperatureSunset = temperatureHigh - MathHelpers.GetRandomDoubleNumber(-2, Math.Min(tempDiff, 2));
            double temperatureDayend = temperatureLow + Rnd.Next(-2, 2);

            double temperature = (temperatureLow + temperatureHigh)/2;

            bool isOvercast = Rnd.Next(100) < average.Precipitation;
            if (isOvercast)
            {
                cover = Weather.CloudCover.Overcast;
                precip = GetPrecipitation(temperature);
            }
            else
            {
                Weather.CloudCover[] notOvercastCovers =
                    {
                        Weather.CloudCover.Clear, Weather.CloudCover.MostlyCloudy,
                        Weather.CloudCover.PartlyCloudy
                    };
                cover = notOvercastCovers[Rnd.Next(notOvercastCovers.Length)];
            }

            var hourlyTemperature = new HourlyWeather[24];

            if (previousWeather == null)
            {
                hourlyTemperature[0] = new HourlyWeather(
                    temperatureLow,
                    cover,
                    cover == Weather.CloudCover.Overcast ? GetPrecipitation(temperatureLow) : Weather.Precipitation.None,
                    windSpeed,
                    windDirection);
            }
            else
            {
                hourlyTemperature[0] = previousWeather.Temperatures[previousWeather.Temperatures.Length - 1];
            }

            double morningSteps = (temperatureSunrise - hourlyTemperature[0].Temperature)/(Weather.Sunrise - 1);

            for (int i = 1; i <= Weather.Sunrise; i++)
            {
                double temp = hourlyTemperature[i - 1].Temperature + morningSteps;
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }

            double daySteps = (temperatureSunset - temperatureSunrise)/(Weather.Sunset - Weather.Sunrise - 1);

            for (int i = Weather.Sunrise + 1; i < Weather.Sunset; i++)
            {
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                double temp = hourlyTemperature[i - 1].Temperature + daySteps;
                if (hourlyCover != hourlyTemperature[i - 1].Cover && hourlyCover == Weather.CloudCover.Overcast)
                {
                    temp -= MathHelpers.GetRandomDoubleNumber(1, 4);
                }
                if (hourlyCover != hourlyTemperature[i - 1].Cover
                    && hourlyTemperature[i - 1].Cover == Weather.CloudCover.Overcast)
                {
                    temp += MathHelpers.GetRandomDoubleNumber(1, 4);
                }

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }

            double eveningSteps = (temperatureDayend - temperatureSunset)/(hourlyTemperature.Length - Weather.Sunset);

            for (int i = Weather.Sunset; i < hourlyTemperature.Length; i++)
            {
                double temp = hourlyTemperature[i - 1].Temperature + eveningSteps;
                Weather.CloudCover hourlyCover = Rnd.Next(3) == 0 ? coverValues[Rnd.Next(coverValues.Length)] : cover;

                int windspeedIndex = windSpeedValues.ToList().IndexOf(windSpeed);
                Weather.eWindSpeed[] hourlyWindspeedValues =
                    {
                        windSpeed, windSpeed, windSpeed,
                        hourlyTemperature[i - 1].WindSpeed,
                        windspeedIndex > 0
                            ? (Weather.eWindSpeed) windspeedIndex - 1
                            : (Weather.eWindSpeed) windspeedIndex + 1,
                        windspeedIndex < windSpeedValues.Length - 1
                            ? (Weather.eWindSpeed) windspeedIndex + 1
                            : (Weather.eWindSpeed) windspeedIndex - 1
                    };
                Weather.eWindSpeed hourlyWindspeed = hourlyWindspeedValues[Rnd.Next(hourlyWindspeedValues.Length)];

                hourlyTemperature[i] = new HourlyWeather(
                    temp,
                    hourlyCover,
                    hourlyCover == Weather.CloudCover.Overcast ? GetPrecipitation(temp) : Weather.Precipitation.None,
                    hourlyWindspeed,
                    windDirection);
            }
            temperatureLow = hourlyTemperature.Min(t => t.Temperature);
            temperatureHigh = hourlyTemperature.Max(t => t.Temperature);

            cover =
                (from c in hourlyTemperature group c by c.Cover into g select new {Cover = g.Key, Qty = g.Count()})
                    .OrderByDescending(g => g.Qty).First().Cover;
            precip =
                (from c in hourlyTemperature group c by c.Precip into g select new {Precip = g.Key, Qty = g.Count()})
                    .OrderByDescending(g => g.Qty).First().Precip;

            var weather = new Weather(
                date,
                windSpeed,
                windDirection,
                cover,
                precip,
                hourlyTemperature,
                temperatureLow,
                temperatureHigh);

            return weather;
        }