]> git.mxchange.org Git - simgear.git/blob - simgear/metar/MetarStation.cpp
Fixes for MSVC++.
[simgear.git] / simgear / metar / MetarStation.cpp
1 // Metar station implementation code
2
3 #include <stdio.h>
4
5 #include "MetarStation.h"
6 #include <algorithm>
7 #define TESTPROG
8 #ifndef TESTPROG
9 // options is too tightly integrated into FlightGear to use in a test program
10 #include <Main/options.hxx>
11 #endif
12 #include <simgear/misc/fgpath.hxx>
13
14
15 std::vector< CMetarStation *> METAR_Stations;
16
17 int CMetarStation::initialized( CMetarStation::initialize() );
18
19 std::string CMetarStation::tempName;
20
21
22 double CMetarStation::decodeDMS( char *b )
23 {
24         double r = 0;
25         double m = 0;
26         double s = 0;
27         if ( *b )
28         {
29                 // Degrees
30                 r = (*b - '0') * 10.0; b++;
31                 r += (*b - '0'); b++;
32                 if ( *b != '-' )
33                 {
34                         r *= 10;
35                         r += (*b - '0'); b++;
36                 }
37                 b++;
38                 // Minutes
39                 m = (*b - '0') * 10.0; b++;
40                 m += (*b - '0'); b++;
41                 r += m/60.0;
42                 if ( *b == '-' )
43                 {
44                         // Seconds
45                         b++;
46                         s = (*b - '0') * 10.0; b++;
47                         s += (*b - '0'); b++;
48                 }
49                 r += s/3600.0;
50                 // Direction (E W N S)
51                 if ( *b == 'W' || *b == 'S' ) r = -r;
52         }
53         return r * DEG_TO_RAD;
54 }
55
56
57 CMetarStation::CMetarStation( 
58         char *s )
59 {
60         char *t;
61         t = strchr( s, ';' ); *t = 0; t++;
62         m_ID = s;
63         s = t; t = strchr( s, ';' ); *t = 0; t++;
64         m_number = atoi( s ) * 1000;
65         s = t; t = strchr( s, ';' ); *t = 0; t++;
66         m_number += atoi( s );
67         s = t; t = strchr( s, ';' ); *t = 0; t++;
68         m_name = s;
69         s = t; t = strchr( s, ';' ); *t = 0; t++;
70         m_state = s;
71         s = t; t = strchr( s, ';' ); *t = 0; t++;
72         m_country = s;
73         s = t; t = strchr( s, ';' ); *t = 0; t++;
74         m_region = atoi( s );
75         s = t; t = strchr( s, ';' ); *t = 0; t++;
76         double latitude = decodeDMS( s );
77         s = t; t = strchr( s, ';' ); *t = 0; t++;
78         double longitude = decodeDMS( s );
79         s = t; t = strchr( s, ';' ); *t = 0; t++;
80         double ulatitude = decodeDMS( s );
81         s = t; t = strchr( s, ';' ); *t = 0; t++;
82         double ulongitude = decodeDMS( s );
83         s = t; t = strchr( s, ';' ); *t = 0; t++;
84         double altitude = atoi( s ) * FEET_TO_METER;
85         s = t; t = strchr( s, ';' ); *t = 0; t++;
86         double ualtitude = atoi( s ) * FEET_TO_METER;
87         Point3D p( longitude, latitude, altitude+EQUATORIAL_RADIUS_M );
88         m_locationPolar = p;
89         m_locationCart = fgPolarToCart3d( p );
90         Point3D up( ulongitude, ulatitude, ualtitude+EQUATORIAL_RADIUS_M );
91         m_upperLocationPolar = up;
92         m_upperLocationCart = fgPolarToCart3d( up );
93         s = t;
94         m_pFlag = s[0];
95 }
96                 // Constructor
97                 // Decodes METAR station string of this format:
98                 // KPUB;72;464;Pueblo, Pueblo Memorial Airport;CO;United States;4;38-17-24N;104-29-54W;38-17-03N;104-29-43W;1440;1420;P
99
100
101 int CMetarStation::initialize()
102 {
103         // Read the list of metar stations, decoding and adding to global list.
104
105         CMetarStation *m;
106         char buf[256];
107
108         // Goto the Flight Gear installation directory
109 #ifdef TESTPROG
110     FGPath weatherPath( "/mkv/Build/FlightGear" );
111 #else
112     FGPath weatherPath( current_options.get_fg_root() );
113 #endif
114
115     weatherPath.append( "Weather/MetarStations" );
116         // Open the metar station list
117         FILE *f = fopen( weatherPath.c_str(), "r" );
118         
119
120         if ( f != NULL )
121         {
122                 // Read each line, create an instance of a station, and add it to the vector
123                 while ( fgets( buf, 256, f) != NULL && feof( f ) == 0 )
124                 {
125                         //std::cout << buf << std::endl;
126                         m = new CMetarStation( buf );
127                         //m->dump();
128                         METAR_Stations.push_back( m );
129                 }
130         
131                 // Close the list
132                 fclose( f );
133                 std::cout << METAR_Stations.size() << " Metar stations" << std::endl;
134                 return 1;
135         }
136         else
137         {
138                 std::cout << "Could not open MetarStations file " << std::endl;
139                 return 0;
140         }
141 }
142
143
144 int CMetarStation::sameName( CMetarStation *m )
145 {
146         return m->m_ID == tempName;
147 }
148
149
150 CMetarStation *CMetarStation::find( std::string stationID )
151 {
152         tempName = stationID;
153         CMetarStation **m = std::find_if( METAR_Stations.begin(), METAR_Stations.end(), sameName );
154         if ( m != METAR_Stations.end() ) return *m;
155         return 0;
156 }
157
158 double bestDist;
159 CMetarStation *bestStation;
160 Point3D curLocation;
161
162 void findHelper( CMetarStation *s )
163 {
164         double dist = s->locationCart().distance3Dsquared( curLocation );
165         if (dist < bestDist )
166         {
167                 bestDist = dist;
168                 bestStation = s;
169         }
170 }
171
172 CMetarStation *CMetarStation::find( Point3D locationCart )
173 {
174         bestDist = 99999999;
175         bestStation = 0;
176         curLocation = locationCart;
177
178         for_each( findHelper );
179         return bestStation;
180 }
181
182
183 void CMetarStation::for_each( void f( CMetarStation *s ) )
184 {
185         std::for_each( METAR_Stations.begin(), METAR_Stations.end(), f );
186 }
187
188
189 void CMetarStation::dump()
190 {
191         std::cout << "ID:" << ID();
192         std::cout << std::endl;
193         std::cout << "number:" << number();
194         std::cout << std::endl;
195         std::cout << "name:" << name();
196         std::cout << std::endl;
197         std::cout << "state:" << state();
198         std::cout << std::endl;
199         std::cout << "country:" << country();
200         std::cout << std::endl;
201         std::cout << "region:" << region();
202         std::cout << std::endl;
203         std::cout << "Location (cart):" << locationCart();
204         std::cout << std::endl;
205         std::cout << "Location (polar):" << locationPolar();
206         std::cout << std::endl;
207         std::cout << "Upper Location (cart):" << upperLocationCart();
208         std::cout << std::endl;
209         std::cout << "Upper Location (polar):" << upperLocationPolar();
210         std::cout << std::endl;
211         std::cout << "P flag:" << pFlag();
212         std::cout << std::endl;
213 }
214
215 std::ostream&
216 operator << ( ostream& out, const CMetarStation& p )
217 {
218     return out 
219                 << "ID:" << p.m_ID << std::endl
220                 << "number:" << p.m_number << std::endl
221                 << "name:" << p.m_name << std::endl
222                 << "state:" << p.m_state << std::endl
223                 << "country:" << p.m_country << std::endl
224                 << "region:" << p.m_region << std::endl
225                 << "Location (cart):" << p.m_locationCart << std::endl
226                 << "Location (polar):" << p.m_locationCart << std::endl
227                 << "Upper Location (cart):" << p.m_upperLocationCart << std::endl
228                 << "Upper Location (polar):" << p.m_upperLocationPolar << std::endl
229                 << "P flag:" << p.m_pFlag << std::endl;
230 }
231