]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
9e62be9e8365c77dad603dd745af366b9b61bde1
[flightgear.git] / src / WeatherCM / FGPhysicalProperties.h
1 /*******-*- Mode: C++ -*-************************************************************
2
3  Header:       FGPhysicalProperties.h   
4  Author:       Christian Mayer
5  Date started: 28.05.99
6
7  ---------- Copyright (C) 1999  Christian Mayer (vader@t-online.de) ----------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  details.
18
19  You should have received a copy of the GNU General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Define the simulated physical properties of the weather
29
30 HISTORY
31 ------------------------------------------------------------------------------
32 28.05.1999 Christian Mayer      Created
33 16.06.1999 Durk Talsma          Portability for Linux
34 20.06.1999 Christian Mayer      Changed struct to class 
35 20.06.1999 Christian Mayer      added lots of consts
36 30.06.1999 Christian Mayer      STL portability
37 11.10.1999 Christian Mayer      changed set<> to map<> on Bernie Bright's 
38                                 suggestion
39 *****************************************************************************/
40
41 /****************************************************************************/
42 /* SENTRY                                                                   */
43 /****************************************************************************/
44 #ifndef FGPhysicalProperties_H
45 #define FGPhysicalProperties_H
46
47 /****************************************************************************/
48 /* INCLUDES                                                                 */
49 /****************************************************************************/
50 #include <Include/compiler.h>
51 #include <vector>
52 #include <map>
53
54 FG_USING_STD(vector);
55 FG_USING_STD(map);
56 FG_USING_NAMESPACE(std);
57
58 #include <Math/point3d.hxx>
59 #include <Voronoi/point2d.h>
60 #include "FGWeatherDefs.h"
61
62 #include "FGAirPressureItem.h"
63
64 #include "FGCloudItem.h"
65 #include "FGSnowRain.h"
66
67 class FGPhysicalProperties
68 {
69 public:
70     typedef WeatherPrecition Altitude;  
71
72     map<Altitude,Point3D> Wind;                     //all Wind vectors
73     map<Altitude,Point3D> Turbulence;               //all Turbulence vectors
74     map<Altitude,WeatherPrecition> Temperature;     //in deg. Kelvin (I *only* accept SI!)
75     FGAirPressureItem AirPressure;                  //in Pascal (I *only* accept SI!)
76     map<Altitude,WeatherPrecition> VaporPressure;   //in Pascal (I *only* accept SI!)
77
78     map<Altitude,FGCloudItem> Clouds;               //amount of covering and type
79
80     WeatherPrecition SnowRainIntensity;     //this also stands for hail, snow,...
81     SnowRainType     snowRainType;          
82     WeatherPrecition LightningProbability;
83
84     FGPhysicalProperties();   //consructor to fill it with FG standart weather
85
86     //return values at specified altitudes
87     Point3D WindAt(const WeatherPrecition& a) const;
88     Point3D TurbulenceAt(const WeatherPrecition& a) const;
89     WeatherPrecition TemperatureAt(const WeatherPrecition& a) const;
90     WeatherPrecition AirPressureAt(const WeatherPrecition& a) const;
91     WeatherPrecition VaporPressureAt(const WeatherPrecition& a) const;
92
93     //for easier access to the cloud stuff:
94     unsigned int getNumberOfCloudLayers(void) const;
95     FGCloudItem getCloudLayer(unsigned int nr) const;
96     
97     FGPhysicalProperties& operator = ( const FGPhysicalProperties& p ); 
98     FGPhysicalProperties& operator *= ( const WeatherPrecition& d ); 
99     FGPhysicalProperties& operator += ( const FGPhysicalProperties& p); 
100     FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p); 
101 };
102
103 typedef vector<FGPhysicalProperties> FGPhysicalPropertiesVector;
104 typedef FGPhysicalPropertiesVector::iterator FGPhysicalPropertiesVectorIt;
105 typedef FGPhysicalPropertiesVector::const_iterator FGPhysicalPropertiesVectorConstIt;
106
107 class FGPhysicalProperties2D;
108 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
109
110 class FGPhysicalProperties2D : public FGPhysicalProperties
111 {
112 public:
113     Point2D p;      //position of the property (lat/lon)
114     friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
115
116     FGPhysicalProperties2D() {}
117
118     FGPhysicalProperties2D(const FGPhysicalProperties& prop, const Point2D& pos) 
119     {
120         Wind = prop.Wind; Turbulence = prop.Turbulence; Temperature = prop.Temperature;
121         AirPressure = prop.AirPressure; VaporPressure = prop.VaporPressure; p = pos;
122     }
123 };
124
125 typedef vector<FGPhysicalProperties2D> FGPhysicalProperties2DVector;
126 typedef FGPhysicalProperties2DVector::iterator FGPhysicalProperties2DVectorIt;
127 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
128
129 inline ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
130 {
131     typedef map<FGPhysicalProperties::Altitude, Point3D         >::const_iterator vector_iterator;
132     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::const_iterator scalar_iterator;
133
134     out << "Position: " << p.p << endl;
135     
136     out << "Stored Wind: ";
137     for (vector_iterator WindIt = p.Wind.begin(); 
138                          WindIt != p.Wind.end(); 
139                          WindIt++)
140         out << "(" << WindIt->first << ") at " << WindIt->second << "m; ";
141     out << endl;
142
143     out << "Stored Turbulence: ";
144     for (vector_iterator TurbulenceIt = p.Turbulence.begin(); 
145                          TurbulenceIt != p.Turbulence.end(); 
146                          TurbulenceIt++)
147         out << "(" << TurbulenceIt->first << ") at " << TurbulenceIt->second << "m; ";
148     out << endl;
149
150     out << "Stored Temperature: ";
151     for (scalar_iterator TemperatureIt = p.Temperature.begin(); 
152                          TemperatureIt != p.Temperature.end(); 
153                          TemperatureIt++)
154         out << TemperatureIt->first << " at " << TemperatureIt->second << "m; ";
155     out << endl;
156
157     out << "Stored AirPressure: ";
158     out << p.AirPressure.getValue(0) << " at " << 0.0 << "m; ";
159     out << endl;
160
161     out << "Stored VaporPressure: ";
162     for (scalar_iterator VaporPressureIt = p.VaporPressure.begin(); 
163                          VaporPressureIt != p.VaporPressure.end(); 
164                          VaporPressureIt++)
165         out << VaporPressureIt->first << " at " << VaporPressureIt->second << "m; ";
166     out << endl;
167
168     return out << endl;
169 }
170
171
172 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
173 {
174     Wind          = p.Wind; 
175     Turbulence    = p.Turbulence; 
176     Temperature   = p.Temperature;
177     AirPressure   = p.AirPressure; 
178     VaporPressure = p.VaporPressure; 
179     return *this;
180 }
181
182 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecition& d )
183 {
184     typedef map<FGPhysicalProperties::Altitude, Point3D         >::iterator vector_iterator;
185     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::iterator scalar_iterator;
186
187     for (vector_iterator WindIt = Wind.begin(); 
188                          WindIt != Wind.end(); 
189                          WindIt++)
190         WindIt->second *= d;
191
192     for (vector_iterator TurbulenceIt = Turbulence.begin(); 
193                          TurbulenceIt != Turbulence.end(); 
194                          TurbulenceIt++)
195         TurbulenceIt->second  *= d;
196
197     for (scalar_iterator TemperatureIt = Temperature.begin(); 
198                          TemperatureIt != Temperature.end(); 
199                          TemperatureIt++)
200         TemperatureIt->second *= d;
201
202     AirPressure *= d;
203
204     for (scalar_iterator VaporPressureIt = VaporPressure.begin(); 
205                          VaporPressureIt != VaporPressure.end(); 
206                          VaporPressureIt++)
207         VaporPressureIt->second *= d;
208
209     return *this;
210 }
211
212 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
213 {
214     typedef map<FGPhysicalProperties::Altitude, Point3D         >::const_iterator vector_iterator;
215     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::const_iterator scalar_iterator;
216
217     for (vector_iterator WindIt = p.Wind.begin(); 
218                          WindIt != p.Wind.end(); 
219                          WindIt++ )
220         if (!Wind.insert(*WindIt).second)           //when it's not inserted => it's already existing
221             Wind[WindIt->first] += WindIt->second;  //=> add the value
222             
223     for (vector_iterator TurbulenceIt = p.Turbulence.begin(); 
224                          TurbulenceIt != p.Turbulence.end(); 
225                          TurbulenceIt++)
226         if (!Turbulence.insert(*TurbulenceIt).second)   
227             Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
228             
229     for (scalar_iterator TemperatureIt = p.Temperature.begin(); 
230                          TemperatureIt != p.Temperature.end(); 
231                          TemperatureIt++)
232         if (!Temperature.insert(*TemperatureIt).second) 
233             Temperature[TemperatureIt->first] += TemperatureIt->second;
234             
235     AirPressure += p.AirPressure.getValue(0.0);
236             
237     for (scalar_iterator VaporPressureIt = p.VaporPressure.begin(); 
238                          VaporPressureIt != p.VaporPressure.end(); 
239                          VaporPressureIt++)
240         if (!VaporPressure.insert(*VaporPressureIt).second)     
241             VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
242
243     return *this;
244 }
245
246 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
247 {
248     typedef map<FGPhysicalProperties::Altitude, Point3D         >::const_iterator vector_iterator;
249     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::const_iterator scalar_iterator;
250
251     for (vector_iterator WindIt = p.Wind.begin(); 
252                          WindIt != p.Wind.end(); 
253                          WindIt++ )
254         if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second)   //when it's not inserted => it's already existing
255             Wind[WindIt->first] -= WindIt->second;                              //=> substract the value
256             
257     for (vector_iterator TurbulenceIt = p.Turbulence.begin(); 
258                          TurbulenceIt != p.Turbulence.end(); 
259                          TurbulenceIt++)
260         if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second) 
261             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
262             
263     for (scalar_iterator TemperatureIt = p.Temperature.begin(); 
264                          TemperatureIt != p.Temperature.end(); 
265                          TemperatureIt++)
266         if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)      
267             Temperature[TemperatureIt->first] -= TemperatureIt->second;
268             
269     AirPressure -= p.AirPressure.getValue(0.0);
270             
271     for (scalar_iterator VaporPressureIt = p.VaporPressure.begin(); 
272                          VaporPressureIt != p.VaporPressure.end(); 
273                          VaporPressureIt++)
274         if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)        
275             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
276
277
278     return *this;
279 }
280
281
282 inline Point3D FGPhysicalProperties::WindAt(const WeatherPrecition& a) const
283 {
284     typedef map<FGPhysicalProperties::Altitude, Point3D>::const_iterator vector_iterator;
285
286     vector_iterator it = Wind.lower_bound(a);
287     vector_iterator it2 = it;
288     it--;
289
290     //now I've got it->alt < a < it2->alt so I can interpolate
291     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
292 }
293
294 inline Point3D FGPhysicalProperties::TurbulenceAt(const WeatherPrecition& a) const
295 {
296     typedef map<FGPhysicalProperties::Altitude, Point3D>::const_iterator vector_iterator;
297
298     vector_iterator it = Turbulence.lower_bound(a);
299     vector_iterator it2 = it;
300     it--;
301
302     //now I've got it->alt < a < it2->alt so I can interpolate
303     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
304 }
305
306 inline WeatherPrecition FGPhysicalProperties::TemperatureAt(const WeatherPrecition& a) const
307 {
308     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::const_iterator scalar_iterator;
309
310     scalar_iterator it = Temperature.lower_bound(a);
311     scalar_iterator it2 = it;
312     it--;
313
314     //now I've got it->alt < a < it2->alt so I can interpolate
315     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
316 }
317
318 inline WeatherPrecition FGPhysicalProperties::AirPressureAt(const WeatherPrecition& a) const
319 {
320     return AirPressure.getValue(a);
321 }
322
323 inline WeatherPrecition FGPhysicalProperties::VaporPressureAt(const WeatherPrecition& a) const
324 {
325     typedef map<FGPhysicalProperties::Altitude, WeatherPrecition>::const_iterator scalar_iterator;
326
327     scalar_iterator it = VaporPressure.lower_bound(a);
328     scalar_iterator it2 = it;
329     it--;
330
331     //now I've got it->alt < a < it2->alt so I can interpolate
332     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
333 }
334
335
336 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecition& b)
337 {
338     return a *= b;
339 }
340
341 inline FGPhysicalProperties operator * (const WeatherPrecition& b, FGPhysicalProperties a)
342 {
343     return a *= b;
344 }
345
346 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
347 {
348     return a += b;
349 }
350
351 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
352 {
353     return a -= b;
354 }
355
356 /****************************************************************************/
357 #endif /*FGPhysicalProperties_H*/
358