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