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