1 // metar interface class 2 // 3 // Written by Melchior FRANZ, started December 2003. 4 // 5 // Copyright (C) 2003 Melchior FRANZ - mfranz@aon.at 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License as 9 // published by the Free Software Foundation; either version 2 of the 10 // License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, but 13 // WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 // 21 // $Id$ 22 23 #ifndef _METAR_HXX 24 #define _METAR_HXX 25 26 #include <vector> 27 #include <map> 28 #include <string> 29 30 #include <simgear/constants.h> 31 32 struct Token { 33 const char *id; 34 const char *text; 35 }; 36 37 const double SGMetarNaN = -1E20; 38 39 class SGMetar; 40 41 class SGMetarVisibility { 42 friend class SGMetar; 43 public: SGMetarVisibility()44 SGMetarVisibility() : 45 _distance(SGMetarNaN), 46 _direction(-1), 47 _modifier(EQUALS), 48 _tendency(NONE) {} 49 50 enum Modifier { 51 NOGO, 52 EQUALS, 53 LESS_THAN, 54 GREATER_THAN 55 }; 56 57 enum Tendency { 58 NONE, 59 STABLE, 60 INCREASING, 61 DECREASING 62 }; 63 64 void set(double dist, int dir = -1, int mod = -1, int tend = -1); 65 getVisibility_m() const66 inline double getVisibility_m() const { return _distance; } getVisibility_ft() const67 inline double getVisibility_ft() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_FEET; } getVisibility_sm() const68 inline double getVisibility_sm() const { return _distance == SGMetarNaN ? SGMetarNaN : _distance * SG_METER_TO_SM; } getDirection() const69 inline int getDirection() const { return _direction; } getModifier() const70 inline int getModifier() const { return _modifier; } getTendency() const71 inline int getTendency() const { return _tendency; } 72 73 protected: 74 double _distance; 75 int _direction; 76 int _modifier; 77 int _tendency; 78 }; 79 80 81 // runway condition (surface and visibility) 82 class SGMetarRunway { 83 friend class SGMetar; 84 public: SGMetarRunway()85 SGMetarRunway() : 86 _deposit(-1), 87 _deposit_string(0), 88 _extent(-1), 89 _extent_string(0), 90 _depth(SGMetarNaN), 91 _friction(SGMetarNaN), 92 _friction_string(0), 93 _comment(0), 94 _wind_shear(false) {} 95 getDeposit() const96 inline int getDeposit() const { return _deposit; } getDepositString() const97 inline const char *getDepositString() const { return _deposit_string; } getExtent() const98 inline double getExtent() const { return _extent; } getExtentString() const99 inline const char *getExtentString() const { return _extent_string; } getDepth() const100 inline double getDepth() const { return _depth; } getFriction() const101 inline double getFriction() const { return _friction; } getFrictionString() const102 inline const char *getFrictionString() const { return _friction_string; } getComment() const103 inline const char *getComment() const { return _comment; } getWindShear() const104 inline bool getWindShear() const { return _wind_shear; } getMinVisibility() const105 inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; } getMaxVisibility() const106 inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; } 107 108 protected: 109 SGMetarVisibility _min_visibility; 110 SGMetarVisibility _max_visibility; 111 int _deposit; 112 const char *_deposit_string; 113 int _extent; 114 const char *_extent_string; 115 double _depth; 116 double _friction; 117 const char *_friction_string; 118 const char *_comment; 119 bool _wind_shear; 120 }; 121 122 123 // cloud layer 124 class SGMetarCloud { 125 friend class SGMetar; 126 public: 127 enum Coverage { 128 COVERAGE_NIL = -1, 129 COVERAGE_CLEAR = 0, 130 COVERAGE_FEW = 1, 131 COVERAGE_SCATTERED = 2, 132 COVERAGE_BROKEN = 3, 133 COVERAGE_OVERCAST = 4 134 }; 135 136 static const char * COVERAGE_NIL_STRING; 137 static const char * COVERAGE_CLEAR_STRING; 138 static const char * COVERAGE_FEW_STRING; 139 static const char * COVERAGE_SCATTERED_STRING; 140 static const char * COVERAGE_BROKEN_STRING; 141 static const char * COVERAGE_OVERCAST_STRING; 142 SGMetarCloud()143 SGMetarCloud() : _coverage(COVERAGE_NIL), _altitude(SGMetarNaN), _type(0), _type_long(0) {} 144 145 void set(double alt, Coverage cov = COVERAGE_NIL ); 146 getCoverage() const147 inline Coverage getCoverage() const { return _coverage; } 148 static Coverage getCoverage( const std::string & coverage ); getAltitude_m() const149 inline double getAltitude_m() const { return _altitude; } getAltitude_ft() const150 inline double getAltitude_ft() const { return _altitude == SGMetarNaN ? SGMetarNaN : _altitude * SG_METER_TO_FEET; } getTypeString() const151 inline const char *getTypeString() const { return _type; } getTypeLongString() const152 inline const char *getTypeLongString() const { return _type_long; } 153 154 protected: 155 Coverage _coverage; // quarters: 0 -> clear ... 4 -> overcast 156 double _altitude; // 1000 m 157 const char *_type; // CU 158 const char *_type_long; // cumulus 159 }; 160 161 162 class SGMetar { 163 public: 164 SGMetar(const std::string& m); 165 ~SGMetar(); 166 167 enum ReportType { 168 NONE, 169 AUTO, 170 COR, 171 RTD 172 }; 173 174 enum Intensity { 175 NIL = 0, 176 LIGHT = 1, 177 MODERATE = 2, 178 HEAVY = 3 179 }; 180 181 struct Weather { WeatherSGMetar::Weather182 Weather() { intensity = NIL; vincinity = false; } 183 Intensity intensity; 184 bool vincinity; 185 std::vector<std::string> descriptions; 186 std::vector<std::string> phenomena; 187 }; 188 getData() const189 inline const char *getData() const { return _data; } getUnusedData() const190 inline const char *getUnusedData() const { return _m; } getProxy() const191 inline bool getProxy() const { return _x_proxy; } getId() const192 inline const char *getId() const { return _icao; } getYear() const193 inline int getYear() const { return _year; } getMonth() const194 inline int getMonth() const { return _month; } getDay() const195 inline int getDay() const { return _day; } getHour() const196 inline int getHour() const { return _hour; } getMinute() const197 inline int getMinute() const { return _minute; } getReportType() const198 inline int getReportType() const { return _report_type; } 199 getWindDir() const200 inline int getWindDir() const { return _wind_dir; } getWindSpeed_mps() const201 inline double getWindSpeed_mps() const { return _wind_speed; } getWindSpeed_kmh() const202 inline double getWindSpeed_kmh() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KMH; } getWindSpeed_kt() const203 inline double getWindSpeed_kt() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_KT; } getWindSpeed_mph() const204 inline double getWindSpeed_mph() const { return _wind_speed == SGMetarNaN ? SGMetarNaN : _wind_speed * SG_MPS_TO_MPH; } 205 getGustSpeed_mps() const206 inline double getGustSpeed_mps() const { return _gust_speed; } getGustSpeed_kmh() const207 inline double getGustSpeed_kmh() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KMH; } getGustSpeed_kt() const208 inline double getGustSpeed_kt() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_KT; } getGustSpeed_mph() const209 inline double getGustSpeed_mph() const { return _gust_speed == SGMetarNaN ? SGMetarNaN : _gust_speed * SG_MPS_TO_MPH; } 210 getWindRangeFrom() const211 inline int getWindRangeFrom() const { return _wind_range_from; } getWindRangeTo() const212 inline int getWindRangeTo() const { return _wind_range_to; } 213 getMinVisibility() const214 inline const SGMetarVisibility& getMinVisibility() const { return _min_visibility; } getMaxVisibility() const215 inline const SGMetarVisibility& getMaxVisibility() const { return _max_visibility; } getVertVisibility() const216 inline const SGMetarVisibility& getVertVisibility() const { return _vert_visibility; } getDirVisibility() const217 inline const SGMetarVisibility *getDirVisibility() const { return _dir_visibility; } 218 getTemperature_C() const219 inline double getTemperature_C() const { return _temp; } getTemperature_F() const220 inline double getTemperature_F() const { return _temp == SGMetarNaN ? SGMetarNaN : 1.8 * _temp + 32; } getDewpoint_C() const221 inline double getDewpoint_C() const { return _dewp; } getDewpoint_F() const222 inline double getDewpoint_F() const { return _dewp == SGMetarNaN ? SGMetarNaN : 1.8 * _dewp + 32; } getPressure_hPa() const223 inline double getPressure_hPa() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure / 100; } getPressure_inHg() const224 inline double getPressure_inHg() const { return _pressure == SGMetarNaN ? SGMetarNaN : _pressure * SG_PA_TO_INHG; } 225 getRain() const226 inline int getRain() const { return _rain; } getHail() const227 inline int getHail() const { return _hail; } getSnow() const228 inline int getSnow() const { return _snow; } getCAVOK() const229 inline bool getCAVOK() const { return _cavok; } 230 231 double getRelHumidity() const; 232 getClouds() const233 inline const std::vector<SGMetarCloud>& getClouds() const { return _clouds; } getRunways() const234 inline const std::map<std::string, SGMetarRunway>& getRunways() const { return _runways; } getWeather() const235 inline const std::vector<std::string>& getWeather() const { return _weather; } getWeather2() const236 inline const std::vector<struct Weather> getWeather2() const { return _weather2; } 237 238 /* Returns human-readable description. If tabtops is 0, we use tab 239 characters. If +ve we use spaces to pad to multiple of <tabstops>. If 240 -1 all sequences of tabs are represented by a single space. */ 241 std::string getDescription(int tabstops) const; 242 243 protected: 244 std::string _url; 245 int _grpcount; 246 bool _x_proxy; 247 char *_data; 248 char *_m; 249 char _icao[5]; 250 int _year; 251 int _month; 252 int _day; 253 int _hour; 254 int _minute; 255 int _report_type; 256 int _wind_dir; 257 double _wind_speed; 258 double _gust_speed; 259 int _wind_range_from; 260 int _wind_range_to; 261 double _temp; 262 double _dewp; 263 double _pressure; 264 int _rain; 265 int _hail; 266 int _snow; 267 bool _cavok; 268 std::vector<struct Weather> _weather2; 269 270 SGMetarVisibility _min_visibility; 271 SGMetarVisibility _max_visibility; 272 SGMetarVisibility _vert_visibility; 273 SGMetarVisibility _dir_visibility[8]; 274 std::vector<SGMetarCloud> _clouds; 275 std::map<std::string, SGMetarRunway> _runways; 276 std::vector<std::string> _weather; 277 278 bool scanPreambleDate(); 279 bool scanPreambleTime(); 280 void useCurrentDate(); 281 282 bool scanType(); 283 bool scanId(); 284 bool scanDate(); 285 bool scanModifier(); 286 bool scanWind(); 287 bool scanVariability(); 288 bool scanVisibility(); 289 bool scanRwyVisRange(); 290 bool scanSkyCondition(); 291 bool scanWeather(); 292 bool scanTemperature(); 293 bool scanPressure(); 294 bool scanRunwayReport(); 295 bool scanWindShear(); 296 bool scanTrendForecast(); 297 bool scanColorState(); 298 bool scanRemark(); 299 bool scanRemainder(); 300 301 int scanNumber(char **str, int *num, int min, int max = 0); 302 bool scanBoundary(char **str); 303 const struct Token *scanToken(char **str, const struct Token *list); 304 void normalizeData(); 305 }; 306 307 #endif // _METAR_HXX 308