Projekt

Obecné

Profil

Stáhnout (10.4 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
    public 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 || 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
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
84
            if (list == null)
85
                return weatherInfo;
86

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

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

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

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

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

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

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

    
133
                values++;
134
            }
135

    
136
            // data from last day
137
            if (values != 0)
138
            {
139
                WeatherInfo dayInfo2 = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / weatherValues, range);
140
                weatherInfo.Add(dayInfo2);
141
            }
142

    
143
            return weatherInfo;
144
        }
145

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

    
158
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
159
            if (list == null)
160
                return weatherInfo;
161

    
162
            // min/max hour taken into account
163
            int[] minmaxHour = new int[] { 7, 18 };
164
            int range = minmaxHour[1] - minmaxHour[0];
165

    
166
            if (interval > range)
167
                return null;
168

    
169
            int indices = (int)Math.Ceiling(range / (double)interval);
170
            int[] to = new int[indices];
171
            double[][] data = new double[indices][];
172
            int[] count = new int[indices];
173
            for (int i = 0; i < to.Length; i++)
174
            {
175
                to[i] = minmaxHour[0] + interval * (i + 1);
176
                data[i] = new double[4];
177
                count[i] = 0;
178
            }
179

    
180
            // first day
181
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
182
            int index;
183
            for (int i = 0; i < list.Count; i++)
184
            {
185
                int currHour = list[i].dateTime.Hour;
186
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
187
                    continue;
188

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

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

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

    
208
                        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);
209
                        if (count[k] != 0)
210
                            weatherInfo.Add(intervalInfo);
211

    
212
                    }
213

    
214
                    lastStartTime = date;
215
                    count = new int[indices];
216
                    for (int l = 0; l < data.Length; l++)
217
                    {
218
                        data[l] = new double[4];
219
                        count[l] = 0;
220
                    }
221
                }
222

    
223
                // if not in allowed time window -> discard
224
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
225
                    continue;
226

    
227
                // find index for current instance
228
                index = 0;
229
                for (int k = 1; k < to.Length; k++)
230
                {
231
                    if (to[k] > list[i].dateTime.Hour && to[k - 1] <= list[i].dateTime.Hour)
232
                    {
233
                        index = k;
234
                        break;
235
                    }
236
                }
237

    
238
                // aggregate data
239
                data[index][0] += list[i].temp;
240
                data[index][1] += list[i].rain;
241
                data[index][2] += list[i].wind;
242
                data[index][3] += list[i].lum * 1000;
243
                count[index]++;
244

    
245
            }
246

    
247
            for (int k = 0; k < to.Length; k++)
248
            {
249
                int raincount = 0;
250
                double rainval = 0; ;
251
                for (int l = 0; l <= k; l++)
252
                {
253
                    raincount += count[l];
254
                    rainval += data[l][1];
255
                }
256

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

    
259
                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);
260
                if (count[k] != 0)
261
                    weatherInfo.Add(intervalInfo);
262
            }
263

    
264
            return weatherInfo;
265
        }
266
    }
267

    
268
}
(6-6/6)