Projekt

Obecné

Profil

Stáhnout (10.2 KB) Statistiky
| Větev: | Tag: | Revize:
1
//
2
// Author: A. Konig
3
//
4

    
5
using ServerApp.Parser.InputData;
6
using ServerApp.Parser.OutputInfo;
7
using System;
8
using System.Collections.Generic;
9
using System.IO;
10

    
11
namespace ServerApp.Parser.Parsers
12
{
13
    /// <summary>
14
    /// Class parsing weather files into instances of WeatherInfo divided by given time interval
15
    /// Data parsed from 7am (included) to 18pm (included)
16
    /// </summary>
17
    /// <author>A. Konig</author>
18
    class WeatherParser
19
    {
20

    
21
        /// <summary> Datafile loader  </summary>
22
        IDataLoader loader;
23

    
24
        /// <summary>
25
        /// Constructor
26
        /// </summary>
27
        /// <param name="loader">Datafile loader</param>
28
        public WeatherParser(IDataLoader loader)
29
        {
30
            this.loader = loader;
31
        }
32

    
33
        /// <summary>
34
        /// Parses weather data to WeatherInfo instances
35
        /// Data parsed from 7am (included) to 18pm (included)
36
        /// </summary>
37
        /// <param name="weatherFiles">Paths to files with weather data files</param>
38
        /// <param name="endTime">End time of related data</param>
39
        /// <param name="startTime">Start time of related data</param>
40
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
41
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
42
        /// <returns></returns>
43
        public List<WeatherInfo> ParseWeatherData(List<string> weatherFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
44
        {
45
            List<WeatherInfo> list = new List<WeatherInfo>();
46

    
47
            if (weatherFiles == null || startTime == null || endTime == null || interval <= 0)
48
                return list;
49

    
50
            // get all files in folder
51
            foreach (string fileName in weatherFiles)
52
            {
53
                if (!File.Exists(fileName))
54
                    continue;
55

    
56
                // parse as one instance per day
57
                List<WeatherInfo> loadedData = null;
58
                if (wholeDay)
59
                    loadedData = ProcessOneWeatherFileAsDays(fileName, startTime, endTime);
60
                // parse according to interval
61
                else
62
                {
63
                    loadedData = ProcessOneWeatherFileAsIntervals(fileName, interval, startTime, endTime);
64
                }
65

    
66
                list.AddRange(loadedData);
67
            }
68

    
69
            return list;
70
        }
71

    
72
        /// <summary>
73
        /// Parses data from one data file as one instance per day
74
        /// </summary>
75
        /// <param name="path">Path ti file</param>
76
        /// <param name="endTime">End time of related data</param>
77
        /// <param name="startTime">Start time of related data</param>
78
        /// <returns>List with WeatherInfo instances</returns>
79
        private List<WeatherInfo> ProcessOneWeatherFileAsDays(string path, DateTime startTime, DateTime endTime)
80
        {
81
            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
82

    
83
            if (!File.Exists(path))
84
                return weatherInfo;
85

    
86
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
87

    
88
            // array with data [temp, rain, wind, lum]
89
            double[] recordedAmount = new double[4];
90
            // min/max hour taken into account
91
            int[] minmaxHour = new int[] { 7, 18 };
92
            // interval length
93
            int range = minmaxHour[1] - minmaxHour[0];
94

    
95
            // first day
96
            DateTime lastStartDay = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
97
            // number of values in day
98
            int values = 0, weatherValues = 0;
99
            for (int i = 0; i < list.Count; i++)
100
            {
101
                int currHour = list[i].dateTime.Hour;
102
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
103
                    continue;
104

    
105
                // start of new day -> make a new instance
106
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
107
                if (!date.Equals(lastStartDay))
108
                {
109
                    WeatherInfo dayInfo = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / weatherValues, range); 
110
                    weatherInfo.Add(dayInfo);
111

    
112
                    recordedAmount = new double[4];
113
                    lastStartDay = date;
114
                    values = 0;
115
                    weatherValues = 0;
116
                }
117

    
118
                // if not in allowed time window -> discard
119
                if (list[i].dateTime < startTime|| list[i].dateTime > endTime)
120
                    continue;
121

    
122
                // aggregate data
123
                recordedAmount[0] += list[i].temp;
124
                recordedAmount[1] += list[i].rain;
125
                recordedAmount[2] += list[i].wind;
126

    
127
                if (ValueToConditions.TransferLuxToConditions(list[i].lum * 1000) != WeatherConditions.Dark)
128
                    recordedAmount[3] += list[i].lum * 1000; weatherValues++;
129

    
130
                values++;
131
            }
132

    
133
            // data from last day
134
            WeatherInfo dayInfo2 = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / values, range); 
135
            weatherInfo.Add(dayInfo2);
136

    
137
            return weatherInfo;
138
        }
139

    
140
        /// <summary>
141
        /// Parses data from one data file as one instance per interval length
142
        /// </summary>
143
        /// <param name="path">Path to file</param>
144
        /// <param name="interval">Interval length</param>
145
        /// <param name="endTime">End time of related data</param>
146
        /// <param name="startTime">Start time of related data</param>
147
        /// <returns>List with ActivityInfo instances</returns>
148
        private List<WeatherInfo> ProcessOneWeatherFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
149
        {
150
            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
151

    
152
            if (!File.Exists(path))
153
                return weatherInfo;
154

    
155
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
156

    
157
            // min/max hour taken into account
158
            int[] minmaxHour = new int[] { 7, 18 };
159
            int range = minmaxHour[1] - minmaxHour[0];
160

    
161
            if (interval > range)
162
                return null;
163

    
164
            int indices = (int)Math.Ceiling(range / (double)interval);
165
            int[] to = new int[indices];
166
            double[][] data = new double[indices][];
167
            int[] count = new int[indices];
168
            for (int i = 0; i < to.Length; i++)
169
            {
170
                to[i] = minmaxHour[0] + interval * (i + 1);
171
                data[i] = new double[4];
172
            }
173

    
174
            // first day
175
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
176
            int index;
177
            for (int i = 0; i < list.Count; i++)
178
            {
179
                int currHour = list[i].dateTime.Hour;
180
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
181
                    continue;
182

    
183
                // start of the day -> make an instance
184
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, list[i].dateTime.Hour, 0, 0);
185

    
186
                // end of the day
187
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
188
                {
189
                    // note down all aggregated data
190
                    for (int k = 0; k < to.Length; k++)
191
                    {
192
                        int raincount = 0;
193
                        double rainval = 0;;
194
                        for (int l = 0; l <= k; l++)
195
                        {
196
                            raincount += count[l];
197
                            rainval += data[l][1];
198
                        }
199

    
200
                        DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
201

    
202
                        WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
203
                        if (count[k] != 0)
204
                            weatherInfo.Add(intervalInfo);
205

    
206
                    }
207

    
208
                    lastStartTime = date;
209
                    count = new int[indices];
210
                    for (int l = 0; l < data.Length; l++)
211
                        data[l] = new double[4];
212
                }
213

    
214
                // if not in allowed time window -> discard
215
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
216
                    continue;
217

    
218
                // find index for current instance
219
                index = 0;
220
                for (int k = 1; k < to.Length; k++)
221
                {
222
                    if (to[k] > list[i].dateTime.Hour && to[k - 1] <= list[i].dateTime.Hour)
223
                    {
224
                        index = k;
225
                        break;
226
                    }
227
                }
228

    
229
                // aggregate data
230
                data[index][0] += list[i].temp;
231
                data[index][1] += list[i].rain;
232
                data[index][2] += list[i].wind;
233
                data[index][3] += list[i].lum * 1000;
234
                count[index]++;
235

    
236
            }
237

    
238
            for (int k = 0; k < to.Length; k++)
239
            {
240
                int raincount = 0;
241
                double rainval = 0; ;
242
                for (int l = 0; l <= k; l++)
243
                {
244
                    raincount += count[l];
245
                    rainval += data[l][1];
246
                }
247

    
248
                DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
249

    
250
                WeatherInfo intervalInfo = new WeatherInfo(stTime, data[k][0] / count[k], (int)((rainval / raincount) * 100), data[k][2] / count[k], data[k][3] / count[k], interval);
251
                if (count[k] != 0)
252
                    weatherInfo.Add(intervalInfo);
253
            }
254

    
255
            return weatherInfo;
256
        }
257
    }
258

    
259
}
(6-6/6)