forked from NOVACProject/MobileDOAS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Common.h
330 lines (269 loc) · 12.1 KB
/
Common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
// Common.h: interface for the Common class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_COMMON_H__D37EDB58_63D7_4142_9CCB_67370BD06621__INCLUDED_)
#define AFX_COMMON_H__D37EDB58_63D7_4142_9CCB_67370BD06621__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <math.h>
#include <vector>
#define MAX_TRAVERSE_SHOWN 16384
/** Not initialized values are set to 'NOT_A_NUMBER' to indicate
that a value is missing.
This can e.g. be the case if only the wind-direction (and not the wind speed)
is known by an element in the database (which can be the case if a the
wind direction was calculated by combining two scans).
*/
#define NOT_A_NUMBER -9999.0
// ----------------------------------------------------------------
// ---------------- MESSAGES USED IN THE PROGRAM ------------------
// ----------------------------------------------------------------
#define WM_PROGRESS WM_USER + 2
#define WM_DONE WM_USER + 3
#define WM_STATUS WM_USER + 4
#define WM_CANCEL WM_USER + 5
#define WM_EVAL WM_USER + 6
#define WM_GOTO_SLEEP WM_USER + 7
// ----------------------------------------------------------------
// ---------------- MATHEMATICAL CONSTANTS ------------------------
// ----------------------------------------------------------------
#define DEGREETORAD 0.01745329251994
#define RADTODEGREE 57.29577951308232
#define HALF_PI 1.57079632679490
#define M_PI 3.14159265358979
#define TWO_PI 6.28318530717959
// ----------------------------------------------------------------
// ------------ SIMPLE MATHEMATICAL FUNCTIONS --------------------
// ----------------------------------------------------------------
// #define round(x) (x < 0 ? ceil((x)-0.5) : floor((x)+0.5))
// ---------------------------------------------------------------
// ---------------- DEFINED CONSTANTS ----------------------------
// ---------------------------------------------------------------
// conversion from ppmm to mg/m^2 for SO2
#define GASFACTOR_SO2 2.66
// conversion from ppmm to mg/m^2 for O3
#define GASFACTOR_O3 1.99
// conversion from ppmm to mg/m^2 for NO2
#define GASFACTOR_NO2 1.93
// conversion from ppmm to mg/m^2 for HCHO
#define GASFACTOR_HCHO 1.25
// the maximum number of channels on the spectrometer that we can handle
#define MAX_N_CHANNELS 2
// The maximum number of fit-regions that we can use at any single time
#define MAX_FIT_WINDOWS 2
// the maximum length of any single spectrum
#define MAX_SPECTRUM_LENGTH 3648
// function returns
#define SUCCESS true
#define FAIL false
struct plotRange{
double maxLat;
double maxLon;
double minLat;
double minLon;
};
typedef struct gpsPosition{
double latitude = 0.0;
double longitude = 0.0;
double altitude = 0.0;
}gpsPosition;
// ---------------------------------------------------------------
// ---------------- GLOBAL FUNCTIONS -----------------------------
// ---------------------------------------------------------------
/** Compares two strings without regard to case.
@return 1 if the strings are equal. @return 0 if the strings are not equal. */
int Equals(const CString &str1, const CString &str2);
/** Compares at most 'nCharacters' of two strings without regard to case.
@param nCharacters - The number of characters to compare
@return 1 if the strings are equal. @return 0 if the strings are not equal. */
int Equals(const CString &str1, const CString &str2, unsigned int nCharacters);
/** A simple function to find out wheather a given file exists or not.
@param - The filename (including path) to the file.
@return 0 if the file does not exist.
@return 1 if the file exist. */
int IsExistingFile(const CString *fileName);
int IsExistingFile(const CString &fileName);
class Common
{
public:
CString m_exePath;
Common();
virtual ~Common();
void WriteLogFile(CString filename, CString txt);
static void GetDateText(char *txt);
static void GetDateText(CString &str);
static void GetTimeText(char *txt);
static void GetTimeText(CString &str);
static void GetDateTimeText(char *txt);
static void GetDateTimeText(CString &str);
static void GetDateTimeTextPlainFormat(char *txt);
static void GetDateTimeTextPlainFormat(CString &str);
// ---------------- PATH MANAGING FUNCTIONS -----------------
/** Get the path of the executable */
void GetExePath();
/** Take out the file name from a long path
@param fileName path of the file */
static void GetFileName(CString& fileName);
/** Take out the directory from a long path name.
@param fileName - the complete path of the file */
static void GetDirectory(CString &fileName);
/** Opens a browser window and lets the user select any number of files */
static std::vector<CString> BrowseForFiles();
/** Opens a browser window and lets the user select one file which matches the provided filter. */
static bool BrowseForFile(char *filter, CString &fileName);
/** Specialization of BrowseForFile, only allows for browsing of evaluation-logs (.txt) */
static bool BrowseForEvaluationLog(CString &fileName);
/** Opens a dialog window and lets the user browse for a filename to save to */
static bool BrowseForFile_SaveAs(TCHAR *filter, CString &fileName);
/** Opens a dialog window and lets the user browse for a directory.
@return true if all is ok,
@return false otherwise */
static bool BrowseForDirectory(CString &folder);
// ---------------- MATHEMATICAL FUNCTIONS --------------------
/** Rounds a given float value to the nearest integer. */
long Round(double d);
/* adapts parameters k and m so that y = k*x + m, in a least square sense.
Algorithm found at: http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html */
static int AdaptStraightLine(double *x, double *y, unsigned int l, double *k, double *m);
/** Guesses the name of the specie in the reference-file whos filename
is given in 'fileName'. */
static void GuessSpecieName(const CString &fileName, CString &specie);
// ------------- BINARY FUNCTIONS ------------------
/** This function swaps the place of the MostSignificantByte and
the LeastSignificantByte of the given number */
static unsigned short Swp(unsigned short in);
// --------------------------------------------------------------------
// ---------------------- DATE & TIME ---------------------------------
// --------------------------------------------------------------------
/** Takes a given year and month and returns the number of days in that month.
The month ranges from 1 to 12. Any illegal values in the month will return 0. */
static int DaysInMonth(int year, int month);
};
/* this function returns a string describing the error code given in 'error'
return value is true if the errorCode can be found, else false. */
bool FormatErrorCode(DWORD error, CString &string);
/* This function returns the distance in meters between the two points defined
by (lat1,lon1) and (lat2, lon2). All angles must be in degrees */
double GPSDistance(double lat1, double lon1, double lat2, double lon2);
/* This function returns the initial bearing (degrees) when travelling from
the point defined by (lat1, lon1) to the point (lat2, lon2).
All angles must be in degrees */
double GPSBearing(double lat1, double lon1, double lat2, double lon2);
/** This function calculates the latitude and longitude for point
which is the distance 'dist' m and bearing 'az' degrees from
the point defied by 'lat1' and 'lon1' */
void CalculateDestination(double lat1, double lon1, double dist, double az, double &lat2, double &lon2);
/* This function calculates the wind factor when travelling from point
1 to point 2 and the wind is defined by 'windAngle' */
double GetWindFactor(double lat1, double lon1, double lat2, double lon2, double windAngle);
// --------------------------------------------------------------------
// ------------------- ARRAY FUNCTIONS --------------------------------
// --------------------------------------------------------------------
/** Searches for the maximum element in the array.
@param pBuffer - The array in which to search for an element.
@param bufLen - The length of the array.
@return - The maximum value in the array */
template <class T> T Max(T *pBuffer, long bufLen){
T maxValue = pBuffer[0];
for(long i = 1; i < bufLen; ++i){
if(pBuffer[i] > maxValue)
maxValue = pBuffer[i];
}
return maxValue;
}
/** Searches for the minimum element in the array.
@param pBuffer - The array in which to search for an element.
@param bufLen - The length of the array.
@return - The minimum value in the array */
template <class T> T Min(T *pBuffer, long bufLen){
T minValue = pBuffer[0];
for(long i = 1; i < bufLen; i++){
if(pBuffer[i] < minValue)
minValue = pBuffer[i];
}
return minValue;
}
/** Calculates the average value of the elements in the array.
It is required that addition and division are defined for
the elements in the array.
@param pBuffer - The array of which to calculate the average.
@param bufLen - The length of the array.
@return - The average value of the elements in the array. */
template <class T> T Average(T *pBuffer, long bufLen){
T sumValue = pBuffer[0];
for(long i = 1; i < bufLen; ++i){
sumValue = sumValue + pBuffer[i];
}
return sumValue / bufLen;
}
/** Calculates the sum of the elements in the array.
It is required that addition is defined for the elements in the array.
@param pBuffer - The array of which to calculate the average.
@param bufLen - The length of the array.
@return - The sum of the elements in the array. */
template <class T> T Sum(T *pBuffer, long bufLen){
T sumValue = pBuffer[0];
for(long i = 1; i < bufLen; ++i){
sumValue = sumValue + pBuffer[i];
}
return sumValue;
}
/** This function finds the 'N' highest values in the supplied array.
On successfull return the array 'output' will be filled with the N highest
values in the input array, sorted in descending order.
@param array - the array to look into
@param nElements - the number of elements in the supplied array
@param output - the output array, must be at least 'N'- elements long
@param N - the number of values to take out.
@param indices - if specified, this will on return the indices for the highest elements. Must have length 'N' */
template <class T> bool FindNHighest(const T array[], long nElements, T output[], int N, int *indices = NULL){
for(int i = 0; i < N; ++i)
output[i] = array[0]; // to get some initial value
// loop through all elements in the array
for(int i = 0; i < nElements; ++i){
// compare this element with all elements in the output array.
for(int j = 0; j < N; ++j){
if(array[i] > output[j]){
// If we found a higher value, shift all other values down one step...
for(int k = N-1; k > j; --k){
output[k] = output[k-1];
if(indices) indices[k] = indices[k-1];
}
output[j] = array[i];
if(indices) indices[j] = i;
break;
}
}
}
return true;
}
/** This function finds the 'N' lowest values in the supplied array.
On successfull return the array 'output' will be filled with the N lowest
values in the input array, sorted in ascending order.
@param array - the array to look into
@param nElements - the number of elements in the supplied array
@param output - the output array, must be at least 'N'- elements long
@param N - the number of values to take out. */
template <class T> bool FindNLowest(const T array[], long nElements, T output[], int N, int *indices = NULL){
for(int i = 0; i < N; ++i)
output[i] = 1e16; // to get some initial value
// loop through all elements in the array
for(int i = 0; i < nElements; ++i){
// compare this element with all elements in the output array.
for(int j = 0; j < N; ++j){
if(array[i] < output[j]){
// If we found a higher value, shift all other values down one step...
for(int k = N-1; k > j; --k){
output[k] = output[k-1];
if(indices) indices[k] = indices[k-1];
}
output[j] = array[i];
if(indices) indices[j] = i;
break;
}
}
}
return true;
}
#endif // !defined(AFX_COMMON_H__D37EDB58_63D7_4142_9CCB_67370BD06621__INCLUDED_)