Projekt

Obecné

Profil

Stáhnout (9.18 KB) Statistiky
| Větev: | Tag: | Revize:
1
using ServerApp.Parser.InputData;
2
using ServerApp.Parser.OutputInfo;
3
using System;
4
using System.Collections.Generic;
5
using System.IO;
6

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

    
17
        /// <summary> Datafile loader  </summary>
18
        DataLoader loader;
19

    
20
        /// <summary>
21
        /// Constructor
22
        /// </summary>
23
        /// <param name="loader">Datafile loader</param>
24
        public WeatherParser(DataLoader loader)
25
        {
26
            this.loader = loader;
27
        }
28

    
29
        /// <summary>
30
        /// Parses weather data to WeatherInfo instances
31
        /// Data parsed from 7am (included) to 18pm (included)
32
        /// </summary>
33
        /// <param name="folder">Folder with weather data files</param>
34
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
35
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
36
        /// <returns></returns>
37
        public List<WeatherInfo> ParseWeatherData(string folder, bool wholeDay = true, int interval = 1)
38
        {
39
            if (!Directory.Exists(folder))
40
                return null;
41

    
42
            List<WeatherInfo> list = new List<WeatherInfo>();
43

    
44
            // get all files in folder
45
            string[] fileEntries = Directory.GetFiles(folder);
46
            foreach (string fileName in fileEntries)
47
            {
48
                List<WeatherInfo> loadedData = null;
49
                
50
                // parse as one instance per day
51
                if (wholeDay)
52
                    loadedData = ProcessOneWeatherFileAsDays(fileName);
53
                // parse according to interval
54
                else
55
                {
56
                    loadedData = ProcessOneWeatherFileAsIntervals(fileName, interval);
57
                }
58

    
59
                list.AddRange(loadedData);
60
            }
61

    
62
            return list;
63
        }
64

    
65
        /// <summary>
66
        /// Parses data from one data file as one instance per day
67
        /// </summary>
68
        /// <param name="path">Path ti file</param>
69
        /// <returns>List with WeatherInfo instances</returns>
70
        private List<WeatherInfo> ProcessOneWeatherFileAsDays(string path)
71
        {
72
            if (!File.Exists(path))
73
                return null;
74

    
75
            List<WeatherInfo> weatherInfo = new List<WeatherInfo>();
76
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
77

    
78
            // array with data [temp, rain, wind, lum]
79
            double[] recordedAmount = new double[4];
80
            // min/max hour taken into account
81
            int[] minmaxHour = new int[] { 7, 18 };
82
            // interval length
83
            int range = minmaxHour[1] - minmaxHour[0];
84

    
85
            // first day
86
            DateTime lastStartDay = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
87
            // number of values in day
88
            int values = 0, weatherValues = 0;
89
            for (int i = 0; i < list.Count; i++)
90
            {
91
                int currHour = list[i].dateTime.Hour;
92
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
93
                    continue;
94

    
95
                // start of new day -> make a new instance
96
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
97
                if (!date.Equals(lastStartDay))
98
                {
99
                    WeatherInfo dayInfo = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / weatherValues, range); 
100
                    weatherInfo.Add(dayInfo);
101

    
102
                    recordedAmount = new double[4];
103
                    lastStartDay = date;
104
                    values = 0;
105
                    weatherValues = 0;
106
                }
107

    
108
                // aggregate data
109
                recordedAmount[0] += list[i].temp;
110
                recordedAmount[1] += list[i].rain;
111
                recordedAmount[2] += list[i].wind;
112

    
113
                if (ValueToConditions.TransferLuxToConditions(list[i].lum * 1000) != WeatherConditions.Dark)
114
                    recordedAmount[3] += list[i].lum * 1000; weatherValues++;
115

    
116
                values++;
117
            }
118

    
119
            // data from last day
120
            WeatherInfo dayInfo2 = new WeatherInfo(lastStartDay, recordedAmount[0] / values, (int)(recordedAmount[1] / values * 100), recordedAmount[2] / values, recordedAmount[3] / values, range); 
121
            weatherInfo.Add(dayInfo2);
122

    
123
            return weatherInfo;
124
        }
125

    
126
        /// <summary>
127
        /// Parses data from one data file as one instance per interval length
128
        /// </summary>
129
        /// <param name="path">Path to file</param>
130
        /// <param name="interval">Interval length</param>
131
        /// <returns>List with ActivityInfo instances</returns>
132
        private List<WeatherInfo> ProcessOneWeatherFileAsIntervals(string path, int interval)
133
        {
134
            if (!File.Exists(path))
135
                return null;
136

    
137
            List<WeatherInfo> loignInfo = new List<WeatherInfo>();
138
            List<WeatherInstance> list = loader.LoadWeatherFile(path);
139

    
140
            // min/max hour taken into account
141
            int[] minmaxHour = new int[] { 7, 18 };
142
            int range = minmaxHour[1] - minmaxHour[0];
143

    
144
            if (interval > range)
145
                return null;
146

    
147
            int indices = (int)Math.Ceiling(range / (double)interval);
148
            int[] to = new int[indices];
149
            double[][] data = new double[indices][];
150
            int[] count = new int[indices];
151
            for (int i = 0; i < to.Length; i++)
152
            {
153
                to[i] = minmaxHour[0] + interval * (i + 1);
154
                data[i] = new double[4];
155
            }
156

    
157
            // first day
158
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
159
            int index;
160
            for (int i = 0; i < list.Count; i++)
161
            {
162
                int currHour = list[i].dateTime.Hour;
163
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
164
                    continue;
165

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

    
169
                // end of the day
170
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
171
                {
172
                    // note down all aggregated data
173
                    for (int k = 0; k < to.Length; k++)
174
                    {
175
                        int raincount = 0;
176
                        double rainval = 0;;
177
                        for (int l = 0; l <= k; l++)
178
                        {
179
                            raincount += count[l];
180
                            rainval += data[l][1];
181
                        }
182

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

    
185
                        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);
186
                        if (count[k] != 0)
187
                            loignInfo.Add(intervalInfo);
188

    
189
                    }
190

    
191
                    lastStartTime = date;
192
                    count = new int[indices];
193
                    for (int l = 0; l < data.Length; l++)
194
                        data[l] = new double[4];
195
                }
196

    
197
                // find index for current instance
198
                index = 0;
199
                for (int k = 1; k < to.Length; k++)
200
                {
201
                    if (to[k] > list[i].dateTime.Hour && to[k - 1] <= list[i].dateTime.Hour)
202
                    {
203
                        index = k;
204
                        break;
205
                    }
206
                }
207

    
208
                // aggregate data
209
                data[index][0] += list[i].temp;
210
                data[index][1] += list[i].rain;
211
                data[index][2] += list[i].wind;
212
                data[index][3] += list[i].lum * 1000;
213
                count[index]++;
214

    
215
            }
216

    
217
            for (int k = 0; k < to.Length; k++)
218
            {
219
                int raincount = 0;
220
                double rainval = 0; ;
221
                for (int l = 0; l <= k; l++)
222
                {
223
                    raincount += count[l];
224
                    rainval += data[l][1];
225
                }
226

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

    
229
                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);
230
                if (count[k] != 0)
231
                    loignInfo.Add(intervalInfo);
232
            }
233

    
234
            return loignInfo;
235
        }
236
    }
237

    
238
}
(6-6/6)