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