CVS: phpweather phpweather.php,1.15,1.16 metar_parser.php,1.13,NONE
Brought to you by:
iridium
|
From: Martin G. <gim...@us...> - 2002-03-17 13:32:30
|
Update of /cvsroot/phpweather/phpweather
In directory usw-pr-cvs1:/tmp/cvs-serv21415
Modified Files:
phpweather.php
Removed Files:
metar_parser.php
Log Message:
The METAR parser is now in class phpweather, so there's no need for
the file metar_parser.php.
Index: phpweather.php
===================================================================
RCS file: /cvsroot/phpweather/phpweather/phpweather.php,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -3 -r1.15 -r1.16
--- phpweather.php 16 Mar 2002 13:55:11 -0000 1.15
+++ phpweather.php 17 Mar 2002 13:32:25 -0000 1.16
@@ -1,112 +1,64 @@
<?php
-/* This code makes sure that the file is only included once. */
-if (defined('PHPWEATHER')) {
- return;
-} else {
- define('PHPWEATHER', true);
-}
/* The location of this file defines the base directory */
define('PHPWEATHER_BASE_DIR', dirname(__FILE__));
-require(PHPWEATHER_BASE_DIR . '/metar_parser.php');
+require(PHPWEATHER_BASE_DIR . '/data_retrieval.php');
/**
- * A container-class for the localized object.
+ * PHP Weather is a class that understands how to parse a raw METAR.
*
- * This class creates a member-object called output.
- * It manages the language of the output.
+ * The decoded METAR is saved in $decoded_metar, in a language-neutral format.
*
* @author Martin Geisler <gim...@gi...>
- * @link http://phpweather.sourceforge.net/ Homepage for PHP Weather.
* @version $Id$
+ * @see $decoded_metar
*/
-class phpweather extends metar_parser {
-
+class phpweather extends data_retrieval {
+
/**
- * The localized output-object.
+ * The decoded METAR is stored here.
*
- * @var object
- */
- var $output;
-
- /**
- * This constructor sets the language when the object is created.
+ * $decoded_metar is an array of arrays. Each sub-array corresponds
+ * to a group of related weather-info. We have cloud-groups,
+ * visibility-groups and so on.
*
- * @param array The initial properties of the object.
- * @access public
+ * @var array
*/
- function phpweather($input) {
- /* We call the parent constructor. */
- $this->metar_parser($input);
-
- /* We also set the language. */
- $this->set_language($this->properties['language']);
-
- }
-
+ var $decoded_metar;
+
/**
- * Sets the language.
- *
- * The language is set by creating an object of the appropriate type,
- * like 'locale_en' for English, 'locale_da' for Danish and so on.
- *
- * @param string The language-code for the language, like 'en' for
- * English, 'hu' for Hungarian and so on.
+ * This constructor does nothing besides passing the input down the
+ * hierarchy.
*
- * @access public
+ * @param array The initial properties of the object.
*/
-
- function set_language($new_language) {
- switch ($new_language) {
- case 'en':
- require_once(PHPWEATHER_BASE_DIR . '/locales/locale_en.php');
- $this->output = new locale_en($this->properties);
- break;
- case 'da':
- require_once(PHPWEATHER_BASE_DIR . '/locales/locale_da.php');
- $this->output = new locale_da($this->properties);
- break;
- case 'hu':
- require_once(PHPWEATHER_BASE_DIR . '/locales/locale_hu.php');
- $this->output = new locale_hu($this->properties);
- break;
- case 'no':
- require_once(PHPWEATHER_BASE_DIR . '/locales/locale_no.php');
- $this->output = new locale_no($this->properties);
- break;
- default:
- $this->error('language not recognized: <code>' . $new_language . '</code> - using <code>en</code>.');
- $this->set_language('en');
- break;
- }
- }
-
- /**
- * Returns the language.
- *
- * @return string The language used by the object.
- * @access public
- */
-
- function get_language() {
- return $this->properties['language'];
+ function metar_parser($input) {
+ /* This class doesn't have any defaults, so it just calls the
+ * parent constructor.
+ */
+ $this->data_retrieval($input);
}
+
/**
* Returns a list of languages.
*
* @return array An associative array with the language codes as the
* keys and the names of the languages as the values.
*
+ * @param string The type of output module you're interested in, eg.
+ * 'text' for the text output module.
+ *
* @access public
*/
+ function get_languages($type) {
+ require(PHPWEATHER_BASE_DIR . '/languages.php');
+ echo "Finding language for $type\n";
- function get_languages() {
- require(PHPWEATHER_BASE_DIR . '/locales/languages.php');
- $dir = opendir(PHPWEATHER_BASE_DIR . '/locales');
+ $dir = opendir(PHPWEATHER_BASE_DIR . '/output');
while($file = readdir($dir)) {
- if (ereg('^locale_([a-z][a-z])\.php$', $file, $regs)) {
+ if (ereg("^pw_${type}_([a-z][a-z])\.php$", $file, $regs)) {
$output[$regs[1]] = $languages[$regs[1]];
}
}
@@ -114,40 +66,628 @@
return $output;
}
+
/**
- * Calls the print_pretty() function of the output-object.
+ * Helper-function used to store temperatures.
*
- * If the METAR is not parsed, then it calls decode_metar() first,
- * before it passes the decoded METAR to the print_pretty() function of
- * the output-object.
+ * Given a numerical temperature $temp in Celsius, coded to tenth of
+ * degree, store in $temp_c, convert to Fahrenheit and store in
+ * $temp_f.
+ *
+ * @param string Temperature to convert, coded to tenth of
+ * degree, like 1015
+ * @param integer Temperature measured in degrees Celsius
+ * @param integer Temperature measured in degrees Fahrenheit
+ * @access private
+ */
+ function store_temp($temp, &$temp_c, &$temp_f) {
+ /*
+ * Note: $temp is converted to negative if $temp > 100.0 (See
+ * Federal Meteorological Handbook for groups T, 1, 2 and 4).
+ * For example, a temperature of 2.6°C and dew point of -1.5°C
+ * would be reported in the body of the report as "03/M01" and the
+ * TsnT'T'T'snT'dT'dT'd group as "T00261015").
+ */
+
+ if ($temp[0] == 1) {
+ $temp[0] = '-';
+ }
+ $temp_c = number_format($temp,1);
+ /* The temperature in Fahrenheit. */
+ $temp_f = number_format($temp * (9/5) + 32, 1);
+ }
+
+
+ /**
+ * Helper-function used to store speeds.
*
- * @return string The pretty-printed weather-report.
- * @access public
+ * $value is converted and stored based on $windunit.
+ *
+ * @param float The value one seeks to convert.
+ * @param string The unit of $value.
+ * @param float &$knots After $value has been converted into knots,
+ * it will be stored in this variable.
+ * @param float &$meterspersec After $value has been converted into
+ * meters per second, it will be stored
+ * in this variable.
+ * @param float &$milesperhour After $value has been converted into
+ * miles per hour, it will be stored
+ * in this variable.
+ * @access private
*/
-
- function print_pretty() {
- if (empty($this->decoded_metar)) {
- $this->decode_metar();
+ function store_speed($value, $windunit, &$knots, &$meterspersec, &$milesperhour) {
+ if ($value == 0) {
+ $knots = 0;
+ $meterspersec = 0;
+ $milesperhour = 0;
+ return;
+ }
+
+ if ($windunit == 'KT') {
+ /* The windspeed measured in knots: */
+ $knots = number_format($value);
+ /* The windspeed measured in meters per second, rounded to one decimal place */
+ $meterspersec = number_format($value * 0.5144, 1);
+ /* The windspeed measured in miles per hour, rounded to one decimal place */
+ $milesperhour = number_format($value * 1.1508, 1);
+ } elseif ($windunit == 'MPS') {
+ /* The windspeed measured in meters per second */
+ $meterspersec = number_format($value);
+ /* The windspeed measured in knots, rounded to one decimal place */
+ $knots = number_format($value / 0.5144, 1);
+ /* The windspeed measured in miles per hour, rounded to one decimal place */
+ $milesperhour = number_format($value / 0.5144 * 1.1508, 1);
+ } elseif ($windunit == 'KMH') {
+ /* The windspeed measured in kilometers per hour */
+ $meterspersec = number_format($value * 1000 / 3600, 1);
+ $knots = number_format($value * 1000 / 3600 / 0.5144, 1);
+ /* The windspeed measured in miles per hour, rounded to one decimal place */
+ $milesperhour = number_format($knots * 1.1508, 1);
}
- return $this->output->print_pretty($this->decoded_metar);
}
-
+
+
/**
- * Calls the print_table() function of the output-object.
+ * Decodes a raw METAR.
*
- * If the METAR is not parsed, then it calls decode_metar() first,
- * before it passes the decoded METAR to the print_table() function of
- * the output-object.
+ * This function loops over the various parts of the raw METAR, and
+ * stores the different bits in $decoded_metar. It uses get_metar() to
+ * retrieve the METAR, so it is not necessary to connect to the database
+ * before you call this function.
*
- * @return string The table-printed weather-report.
+ * @return array The decoded METAR.
+ * @see $decoded_metar
* @access public
*/
+ function decode_metar() {
+ /* initialization */
+ $cloud_group_nr = 0;
+ $weather_group_nr = 0;
+ $visibility_group_nr = 0;
+ $runway_group_nr = 0;
+ $temp_visibility_miles = '';
+
+ $decoded_metar['remarks'] = '';
+ /* There should always be at least one cloud-group, even if it's
+ empty. */
+ $decoded_metar['clouds'][] = array();
- function print_table() {
- if (empty($this->decoded_metar)) {
- $this->decode_metar();
+
+ $decoded_metar['metar'] = $this->get_metar();
+ $decoded_metar['location'] = $this->get_location();
+
+ $parts = explode(' ', $this->metar);
+ $num_parts = count($parts);
+ for ($i = 0; $i < $num_parts; $i++) {
+ $part = $parts[$i];
+
+ if (ereg('RMK|TEMPO|BECMG|INTER', $part)) {
+ /* The rest of the METAR is either a remark or temporary
+ * information. We skip the rest of the METAR.
+ */
+ $decoded_metar['remarks'] .= ' ' . $part;
+ break;
+ } elseif ($part == 'METAR') {
+ /*
+ * Type of Report: METAR
+ */
+ $decoded_metar['type'] = 'METAR';
+ } elseif ($part == 'SPECI') {
+ /*
+ * Type of Report: SPECI
+ */
+ $decoded_metar['type'] = 'SPECI';
+ } elseif (ereg('^[A-Z]{4}$', $part) && ! isset($decoded_metar['station'])) {
+ /*
+ * Station Identifier
+ */
+ $decoded_metar['station'] = $part;
+ } elseif (ereg('([0-9]{2})([0-9]{2})([0-9]{2})Z', $part, $regs)) {
+ /*
+ * Date and Time of Report.
+ *
+ * We return a standard Unix UTC/GMT timestamp suitable for
+ * gmdate().
+ * Due to a bug in PHP, on some systems the time reported may
+ * be incorrect. If you experience this, you can set
+ * $this->properties['offset'] to be the offset to add. For
+ * example, if your times generated are 1 hour too early (so
+ * metars appear an hour older than they are), set
+ * $this->properties['offset'] to be +1 in your defaults.php
+ * file.
+ */
+ if ($regs[1] > gmdate('j')) {
+ /* The day is greather that the current day of month => the
+ * report is from last month.
+ */
+ $month = gmdate('n') - 1;
+ } else {
+ $month = gmdate('n');
+ }
+ $decoded_metar['time'] = gmmktime($regs[2]+$this->properties['offset'], $regs[3], 0, $month, $regs[1], gmdate('Y'));
+ } elseif (ereg('(AUTO|COR|RTD|CC[A-Z]|RR[A-Z])', $part, $regs)) {
+
+ /*
+ * Report Modifier: AUTO, COR, CCx or RRx
+ */
+
+ $decoded_metar['report_mod'] = $regs[1];
+ } elseif (ereg('([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?(KT|MPS|KMH)', $part, $regs)) {
+
+ /* Wind Group */
+
+ $decoded_metar['wind']['deg'] = $regs[1];
+
+ $this->store_speed($regs[2],
+ $regs[4],
+ $decoded_metar['wind']['knots'],
+ $decoded_metar['wind']['meters_per_second'],
+ $decoded_metar['wind']['miles_per_hour']
+ );
+
+ if (!empty($regs[3])) {
+
+ /* We have a report with information about the gust.
+ * First we have the gust measured in knots.
+ */
+ $this->store_speed($regs[3],
+ $regs[4],
+ $decoded_metar['wind']['gust_knots'],
+ $decoded_metar['wind']['gust_meters_per_second'],
+ $decoded_metar['wind']['gust_miles_per_hour']);
+ }
+ } elseif (ereg('^([0-9]{3})V([0-9]{3})$', $part, $regs)) {
+
+ /*
+ * Variable wind-direction
+ */
+
+ $decoded_metar['wind']['var_beg'] = $regs[1];
+ $decoded_metar['wind']['var_end'] = $regs[2];
+ } elseif(ereg('^([0-9]{4})([NS]?[EW]?)$', $part, $regs)) {
+
+ /*
+ * Visibility in meters (4 digits only)
+ */
+
+ if ($regs[1] == '0000') {
+
+ /* Special low value */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['prefix'] = -1; /* Less than */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['meter'] = 50;
+ $decoded_metar['visibility'][$visibility_group_nr]['km'] = 0.05;
+ $decoded_metar['visibility'][$visibility_group_nr]['ft'] = 164;
+ $decoded_metar['visibility'][$visibility_group_nr]['miles'] = 0.031;
+ } elseif ($regs[1] == '9999') {
+
+ /* Special high value */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['prefix'] = 1;
+ /* Greater than */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['meter'] = 10000;
+ $decoded_metar['visibility'][$visibility_group_nr]['km'] = 10;
+ $decoded_metar['visibility'][$visibility_group_nr]['ft'] = 32800;
+ $decoded_metar['visibility'][$visibility_group_nr]['miles'] = 6.2;
+ } else {
+
+ /* Normal visibility, returned in both small and large units. */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['km'] = number_format($regs[1]/1000, 1);
+ $decoded_metar['visibility'][$visibility_group_nr]['miles'] = number_format($regs[1]/1609.344, 1);
+ $decoded_metar['visibility'][$visibility_group_nr]['meter'] = $regs[1] * 1;
+ $decoded_metar['visibility'][$visibility_group_nr]['ft'] = round($regs[1] * 3.28084);
+ }
+ if (!empty($regs[2])) {
+ $decoded_metar['visibility'][$visibility_group_nr]['dir'] = $regs[2];
+ }
+
+ /* We increment $visibility_group_nr so that it's ready for
+ the next group. */
+ $visibility_group_nr++;
+
+ } elseif (ereg('^[0-9]$', $part)) {
+
+ /*
+ * Temp Visibility Group, single digit followed by space.
+ */
+
+ $temp_visibility_miles = $part;
+ } elseif (ereg('^M?(([0-9]?)[ ]?([0-9])(/?)([0-9]*))SM$', $temp_visibility_miles . ' ' . $part, $regs)) {
+
+ /*
+ * Visibility Group
+ */
+
+ if ($regs[4] == '/') {
+ $vis_miles = $regs[2] + $regs[3]/$regs[5];
+ } else {
+ $vis_miles = $regs[1];
+ }
+ if ($regs[0][0] == 'M') {
+
+ /* Prefix - less than */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['prefix'] = -1; /* Less than */
+
+ }
+
+ /* The visibility measured in miles */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['miles'] = number_format($vis_miles, 1);
+
+ /* The visibility measured in feet */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['ft'] = round($vis_miles * 5280, 1);
+
+ /* The visibility measured in kilometers */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['km'] = number_format($vis_miles * 1.6093, 1);
+
+ /* The visibility measured in meters */
+
+ $decoded_metar['visibility'][$visibility_group_nr]['meter'] = round($vis_miles * 1609.3);
+
+ /* We increment $visibility_group_nr so that it's ready for
+ the next group. */
+ $visibility_group_nr++;
+
+ } elseif ($part == 'CAVOK') {
+
+ /* CAVOK: Used when the visibility is greater than 10
+ * kilometers, the lowest cloud-base is at 5000 feet or more
+ * and there is no significant weather.
+ */
+
+ /* Greater than */
+ $decoded_metar['visibility'][$visibility_group_nr]['prefix'] = 1;
+
+ $decoded_metar['visibility'][$visibility_group_nr]['km'] = 10;
+ $decoded_metar['visibility'][$visibility_group_nr]['meter'] = 10000;
+ $decoded_metar['visibility'][$visibility_group_nr]['miles'] = 6.2;
+ $decoded_metar['visibility'][$visibility_group_nr]['ft'] = 32800;
+ $decoded_metar['cloud_group1']['condition'] = 'CAVOK';
+
+ /* We increment $visibility_group_nr so that it's ready for
+ the next group. */
+ $visibility_group_nr++;
+
+ } elseif (ereg('^R([0-9]{2})([RLC]?)/([MP]?)([0-9]{4})([DNU]?)V?(P?)([0-9]{4})?([DNU]?)$', $part, $regs)) {
+
+ /* Runway-group */
+
+ $decoded_metar['runway'][$runway_group_nr]['nr'] = $regs[1];
+ if (!empty($regs[2])) {
+ $decoded_metar['runway'][$runway_group_nr]['approach'] = $regs[2];
+ }
+
+ if (!empty($regs[7])) {
+
+ /* We have both min and max visibility since $regs[7] holds
+ * the max visibility.
+ */
+
+ if (!empty($regs[5])) {
+ /* $regs[5] is tendency for min visibility. */
+ $decoded_metar['runway'][$runway_group_nr]['min_tendency'] = $regs[5];
+ }
+
+ if (!empty($regs[8])) {
+ /* $regs[8] is tendency for max visibility. */
+ $decoded_metar['runway'][$runway_group_nr]['max_tendency'] = $regs[8];
+ }
+
+ if ($regs[3] == 'M') {
+
+ /* Less than. */
+
+ $decoded_metar['runway'][$runway_group_nr]['min_prefix'] = -1;
+ }
+ $decoded_metar['runway'][$runway_group_nr]['min_meter'] = $regs[4] * 1;
+ $decoded_metar['runway'][$runway_group_nr]['min_ft'] = round($regs[4] * 3.2808);
+
+ if ($regs[6] == 'P') {
+
+ /* Greater than. */
+
+ $decoded_metar['runway'][$runway_group_nr]['max_prefix'] = 1;
+ }
+ $decoded_metar['runway'][$runway_group_nr]['max_meter'] = $regs[7] * 1;
+ $decoded_metar['runway'][$runway_group_nr]['max_ft'] = round($regs[7] * 3.2808);
+
+ } else {
+
+ /* We only have a single visibility. */
+
+ if (!empty($regs[5])) {
+ /* $regs[5] holds the tendency for visibility. */
+ $decoded_metar['runway'][$runway_group_nr]['tendency'] = $regs[5];
+ }
+
+ if ($regs[3] == 'M') {
+
+ /* Less than. */
+
+ $decoded_metar['runway'][$runway_group_nr]['prefix'] = -1;
+ } elseif ($regs[3] == 'P') {
+
+ /* Greater than. */
+
+ $decoded_metar['runway'][$runway_group_nr]['prefix'] = 1;
+ }
+ $decoded_metar['runway'][$runway_group_nr]['meter'] = $regs[4] * 1;
+ $decoded_metar['runway'][$runway_group_nr]['ft'] = round($regs[4] * 3.2808);
+ }
+
+ /* We increment $runway_group_nr so that it's ready for the
+ next group. */
+ $runway_group_nr++;
+
+ } elseif (ereg('^(VC)?' . /* Proximity */
+ '(-|\+)?' . /* Intensity */
+ '(MI|PR|BC|DR|BL|SH|TS|FZ)?' . /* Descriptor */
+ '((DZ|RA|SN|SG|IC|PE|GR|GS|UP)+)?' . /* Precipitation */
+ '(BR|FG|FU|VA|DU|SA|HZ|PY)?' . /* Obscuration */
+ '(PO|SQ|FC|SS)?$', /* Other */
+ $part, $regs)) {
+
+ /*
+ * Current weather-group.
+ */
+
+ $decoded_metar['weather'][$weather_group_nr]['proximity'] = $regs[1];
+ $decoded_metar['weather'][$weather_group_nr]['intensity'] = $regs[2];
+ $decoded_metar['weather'][$weather_group_nr]['descriptor'] = $regs[3];
+ $decoded_metar['weather'][$weather_group_nr]['precipitation'] = $regs[4];
+ $decoded_metar['weather'][$weather_group_nr]['obscuration'] = $regs[6];
+ $decoded_metar['weather'][$weather_group_nr]['other'] = $regs[7];
+
+
+ /* We increment $weather_group_nr so that it's ready for the
+ next group. */
+ $weather_group_nr++;
+
+ } elseif ($part == 'SKC' || $part == 'CLR') {
+
+ /* Cloud-group */
+
+
+
+ /* Again we have to translate the code-characters to a
+ * meaningful string.
+ */
+
+ $decoded_metar['clouds'][ $cloud_group_nr]['condition'] = $part;
+
+ /* We increment $cloud_group_nr so that it's ready for the
+ next group. */
+ $cloud_group_nr++;
+
+ } elseif (ereg('^(VV|FEW|SCT|BKN|OVC)([0-9]{3}|///)(CB|TCU)?$', $part, $regs)) {
+
+ /* We have found (another) a cloud-layer-group. */
+
+ $decoded_metar['clouds'][$cloud_group_nr]['condition'] = $regs[1];
+ if (!empty($regs[3])) {
+ $decoded_metar['clouds'][$cloud_group_nr]['cumulus'] = $regs[3];
+ }
+ if ($regs[2] == '000') {
+
+ /* '000' is a special height. */
+
+ $decoded_metar['clouds'][$cloud_group_nr]['ft'] = 100;
+ $decoded_metar['clouds'][$cloud_group_nr]['meter'] = 30;
+ $decoded_metar['clouds'][$cloud_group_nr]['prefix'] = -1; /* Less than */
+ } elseif ($regs[2] == '///') {
+
+ /* '///' means height nil */
+
+ $decoded_metar['clouds'][$cloud_group_nr]['ft'] = 'nil';
+ $decoded_metar['clouds'][$cloud_group_nr]['meter'] = 'nil';
+ } else {
+ $decoded_metar['clouds'][$cloud_group_nr]['ft'] = $regs[2] *100;
+ $decoded_metar['clouds'][$cloud_group_nr]['meter'] = round($regs[2] * 30.48);
+ }
+
+ /* We increment $cloud_group_nr so that it's ready for the
+ next group. */
+ $cloud_group_nr++;
+
+ } elseif (ereg('^(M?[0-9]{2})/(M?[0-9]{2})?$', $part, $regs)) {
+
+ /*
+ * Temperature/Dew Point Group.
+ *
+ * The temperature and dew-point measured in Celsius and Fahrenheit.
+ */
+
+ $decoded_metar['temperature']['temp_c'] = round(strtr($regs[1], 'M', '-'));
+ $decoded_metar['temperature']['temp_f'] = round(strtr($regs[1], 'M', '-') * (9/5) + 32);
+ if (!empty($regs[2])) {
+ $decoded_metar['temperature']['dew_c'] = round(strtr($regs[2], 'M', '-'));
+ $decoded_metar['temperature']['dew_f'] = round(strtr($regs[2], 'M', '-') * (9/5) + 32);
+ }
+ } elseif(ereg('A([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Altimeter.
+ * The pressure measured in inHg.
+ */
+
+ $decoded_metar['altimeter']['inhg'] = number_format($regs[1]/100, 2);
+
+ /* The pressure measured in mmHg, hPa and atm */
+
+ $decoded_metar['altimeter']['mmhg'] = number_format($regs[1] * 0.254, 1, '.', '');
+ $decoded_metar['altimeter']['hpa'] = round($regs[1] * 0.33864);
+ $decoded_metar['altimeter']['atm'] = number_format($regs[1] * 3.3421e-4, 3, '.', '');
+ } elseif(ereg('Q([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Altimeter.
+ * The specification doesn't say anything about
+ * the Qxxxx-form, but it's in the METARs.
+ */
+
+ /* The pressure measured in hPa */
+
+ $decoded_metar['altimeter']['hpa'] = round($regs[1]);
+
+ /* The pressure measured in mmHg, inHg and atm */
+
+ $decoded_metar['altimeter']['mmhg'] = number_format($regs[1] * 0.75006, 1, '.', '');
+ $decoded_metar['altimeter']['inhg'] = number_format($regs[1] * 0.02953, 2);
+ $decoded_metar['altimeter']['atm'] = number_format($regs[1] * 9.8692e-4, 3, '.', '');
+ } elseif (ereg('^T([0-9]{4})([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Temperature/Dew Point Group, coded to tenth of degree Celsius.
+ */
+
+ $this->store_temp($regs[1] / 10,
+ $decoded_metar['temperature']['temp_c'],
+ $decoded_metar['temperature']['temp_f']);
+ $this->store_temp($regs[2] / 10,
+ $decoded_metar['temperature']['dew_c'],
+ $decoded_metar['temperature']['dew_f']);
+ } elseif (ereg('^T([0-9]{4}$)', $part, $regs)) {
+ $this->store_temp($regs[1],
+ $decoded_metar['temperature']['temp_c'],
+ $decoded_metar['temperature']['temp_f']);
+ } elseif (ereg('^1([0-9]{4}$)', $part, $regs)) {
+
+ /*
+ * 6 hour maximum temperature Celsius, coded to tenth of degree
+ */
+
+ $this->store_temp($regs[1] / 10,
+ $decoded_metar['temp_min_max']['max6h_c'],
+ $decoded_metar['temp_min_max']['max6h_f']);
+ } elseif (ereg('^2([0-9]{4}$)', $part, $regs)) {
+
+ /*
+ * 6 hour minimum temperature Celsius, coded to tenth of degree
+ */
+ $this->store_temp($regs[1] / 10,
+ $decoded_metar['temp_min_max']['min6h_c'],
+ $decoded_metar['temp_min_max']['min6h_f']);
+ } elseif (ereg('^4([0-9]{4})([0-9]{4})$', $part, $regs)) {
+
+ /*
+ * 24 hour maximum and minimum temperature Celsius, coded to
+ * tenth of degree
+ */
+ $this->store_temp($regs[1] / 10,
+ $decoded_metar['temp_min_max']['max24h_c'],
+ $decoded_metar['temp_min_max']['max24h_f']);
+ $this->store_temp($regs[2] / 10,
+ $decoded_metar['temp_min_max']['min24h_c'],
+ $decoded_metar['temp_min_max']['min24h_f']);
+ } elseif(ereg('^P([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Precipitation during last hour in hundredths of an inch
+ */
+ if ($regs[1] == '0000') {
+ $decoded_metar['precipitation']['in'] = -1;
+ $decoded_metar['precipitation']['mm'] = -1;
+ } else {
+ $decoded_metar['precipitation']['in'] = number_format($regs[1]/100, 2);
+ $decoded_metar['precipitation']['mm'] = number_format($regs[1]*0.254, 2);
+ }
+ } elseif(ereg('^6([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Precipitation during last 3 or 6 hours in hundredths of an
+ * inch.
+ */
+ if ($regs[1] == '0000') {
+ $decoded_metar['precipitation']['in_6h'] = -1;
+ $decoded_metar['precipitation']['mm_6h'] = -1;
+ } else {
+ $decoded_metar['precipitation']['in_6h'] = number_format($regs[1]/100, 2);
+ $decoded_metar['precipitation']['mm_6h'] = number_format($regs[1]*0.254, 2);
+ }
+ } elseif(ereg('^7([0-9]{4})', $part, $regs)) {
+
+ /*
+ * Precipitation during last 24 hours in hundredths of an inch.
+ */
+ if ($regs[1] == '0000') {
+ $decoded_metar['precipitation']['in_24h'] = -1;
+ $decoded_metar['precipitation']['mm_24h'] = -1;
+ } else {
+ $decoded_metar['precipitation']['in_24h'] = number_format($regs[1]/100, 2, '.', '');
+ $decoded_metar['precipitation']['mm_24h'] = number_format($regs[1]*0.254, 2, '.', '');
+ }
+ } elseif(ereg('^4/([0-9]{3})', $part, $regs)) {
+
+ /*
+ * Snow depth in inches
+ */
+
+ if ($regs[1] == '0000') {
+ $decoded_metar['precipitation']['snow_in'] = -1;
+ $decoded_metar['precipitation']['snow_mm'] = -1;
+ } else {
+ $decoded_metar['precipitation']['snow_in'] = $regs[1] * 1;
+ $decoded_metar['precipitation']['snow_mm'] = round($regs[1] * 25.4);
+ }
+ } else {
+
+ /*
+ * If we couldn't match the group, we assume that it was a
+ * remark.
+ */
+
+ $decoded_metar['remarks'] .= ' ' . $part;
+ }
}
- return $this->output->print_table($this->decoded_metar);
- }
+
+ /*
+ * Relative humidity
+ */
+
+ if (!empty($decoded_metar['temperature']['temp_c']) &&
+ !empty($decoded_metar['temperature']['dew_c'])) {
+ $decoded_metar['rel_humidity'] =
+ number_format(pow(10, (1779.75 * ($decoded_metar['temperature']['dew_c'] -
+ $decoded_metar['temperature']['temp_c'])
+ / ((237.3 + $decoded_metar['temperature']['dew_c']) *
+ (237.3 + $decoded_metar['temperature']['temp_c']))
+ + 2)), 1);
+ }
+
+ /* Finally we store our decoded METAR in $this->decoded_metar so
+ * that other methods can use it.
+ */
+
+ $this->decoded_metar = $decoded_metar;
+ return $decoded_metar;
+ }
}
+
+?>
--- metar_parser.php DELETED ---
|