\n"; print_wxInfo($wxInfo); // Modify this function to fit your needs. ?>
Lookup Station Info

Get weather info from station:           

Links:

Listings of Surface Observations for US

Lookup Meteorological Station Information

NWS METAR Info

Woody's PHP Scripts, Martin Geisler's PHP Weather, Todd Hammer's Phorecast

5) $distance = round($distance); if ($distance <= 1) $unit = ' mile'; else $unit = ' miles'; $wxInfo['VISIBILITY'] = $distance . $unit; $metarPtr++; $group++; } elseif ($part == 'CAVOK') { // good weather $wxInfo['VISIBILITY'] = 'greater than 7 miles'; // or 10 km $wxInfo['CONDITIONS'] = ''; $wxInfo['CLOUDS'] = 'clear skies'; $metarPtr++; $group += 4; // can skip the next 3 groups } else { $group++; } } function get_runway($part, &$metarPtr, &$group, &$wxInfo) { // Ignore runway information if present. Maybe called a second time. // Format is Rrrr/vvvvFT where rrr = runway number and vvvv = visibility in feet. if (substr($part,0,1) == 'R') $metarPtr++; else $group++; } function get_conditions($part, &$metarPtr, &$group, &$wxInfo) { // Decodes current weather conditions. This function maybe called several times // to decode all conditions. To learn more about weather condition codes, visit section // 12.6.8 - Present Weather Group of the Federal Meteorological Handbook No. 1 at // www.nws.noaa.gov/oso/oso1/oso12/fmh1/fmh1ch12.htm static $conditions = ''; static $wxCode = array( 'VC' => 'nearby', 'MI' => 'shallow', 'PR' => 'partial', 'BC' => 'patches of', 'DR' => 'low drifting', 'BL' => 'blowing', 'SH' => 'showers', 'TS' => 'thunderstorm', 'FZ' => 'freezing', 'DZ' => 'drizzle', 'RA' => 'rain', 'SN' => 'snow', 'SG' => 'snow grains', 'IC' => 'ice crystals', 'PE' => 'ice pellets', 'GR' => 'hail', 'GS' => 'small hail', // and/or snow pellets 'UP' => 'unknown', 'BR' => 'mist', 'FG' => 'fog', 'FU' => 'smoke', 'VA' => 'volcanic ash', 'DU' => 'widespread dust', 'SA' => 'sand', 'HZ' => 'haze', 'PY' => 'spray', 'PO' => 'well-developed dust/sand whirls', 'SQ' => 'squalls', 'FC' => 'funnel cloud, tornado, or waterspout', 'SS' => 'sandstorm/duststorm'); if (ereg('^(-|\+|VC)?(TS|SH|FZ|BL|DR|MI|BC|PR|RA|DZ|SN|SG|GR|GS|PE|IC|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$',$part,$pieces)) { if (strlen($conditions) == 0) $join = ''; else $join = ' & '; if (substr($part,0,1) == '-') { $prefix = 'light '; $part = substr($part,1); } elseif (substr($part,0,1) == '+') { $prefix = 'heavy '; $part = substr($part,1); } else $prefix = ''; // moderate conditions have no descriptor $conditions .= $join . $prefix; // The 'showers' code 'SH' is moved behind the next 2-letter code to make the English translation read better. if (substr($part,0,2) == 'SH') $part = substr($part,2,2) . substr($part,0,2). substr($part, 4); while ($code = substr($part,0,2)) { $conditions .= $wxCode[$code] . ' '; $part = substr($part,2); } $wxInfo['CONDITIONS'] = $conditions; $metarPtr++; } else { $wxInfo['CONDITIONS'] = $conditions; $group++; } } function get_cloud_cover($part, &$metarPtr, &$group, &$wxInfo) { // Decodes cloud cover information. This function maybe called several times // to decode all cloud layer observations. Only the last layer is saved. // Format is SKC or CLR for clear skies, or cccnnn where ccc = 3-letter code and // nnn = altitude of cloud layer in hundreds of feet. 'VV' seems to be used for // very low cloud layers. (Other conversion factor: 1 m = 3.28084 ft) static $cloudCode = array( 'SKC' => 'clear skies', 'CLR' => 'clear skies', 'FEW' => 'partly cloudy', 'SCT' => 'scattered clouds', 'BKN' => 'mostly cloudy', 'OVC' => 'overcast', 'VV' => 'vertical visibility'); if ($part == 'SKC' || $part == 'CLR') { $wxInfo['CLOUDS'] = $cloudCode[$part]; $metarPtr++; $group++; } else { if (ereg('^([A-Z]{2,3})([0-9]{3})',$part,$pieces)) { // codes for CB and TCU are ignored $wxInfo['CLOUDS'] = $cloudCode[$pieces[1]]; if ($pieces[1] == 'VV') { $altitude = (integer) 100 * $pieces[2]; // units are feet $wxInfo['CLOUDS'] .= " to $altitude ft"; } $metarPtr++; } else { $group++; } } } function get_temperature($part, &$metarPtr, &$group, &$wxInfo) { // Decodes temperature and dew point information. Relative humidity is calculated. Also, // depending on the temperature, Heat Index or Wind Chill Temperature is calculated. // Format is tt/dd where tt = temperature and dd = dew point temperature. All units are // in Celsius. A 'M' preceeding the tt or dd indicates a negative temperature. Some // stations do not report dew point, so the format is tt/ or tt/XX. function get_heat_index($tempF, $rh, &$wxInfo) { // Calculate Heat Index based on temperature in F and relative humidity (65 = 65%) if ($tempF > 79 && $rh > 39) { $hiF = -42.379 + 2.04901523 * $tempF + 10.14333127 * $rh - 0.22475541 * $tempF * $rh; $hiF += -0.00683783 * pow($tempF, 2) - 0.05481717 * pow($rh, 2); $hiF += 0.00122874 * pow($tempF, 2) * $rh + 0.00085282 * $tempF * pow($rh, 2); $hiF += -0.00000199 * pow($tempF, 2) * pow($rh, 2); $hiF = round($hiF); $hiC = round(($hiF - 32) / 1.8); $wxInfo['HEAT INDEX'] = "$hiF°F ($hiC°C)"; } } function get_wind_chill($tempF, &$wxInfo) { // Calculate Wind Chill Temperature based on temperature in F and // wind speed in miles per hour if ($tempF < 51 && $wxInfo['WIND'] != 'calm') { $pieces = explode(' ', $wxInfo['WIND']); $windspeed = (integer) $pieces[2]; // wind speed must be in miles per hour if ($windspeed > 3) { $chillF = 35.74 + 0.6215 * $tempF - 35.75 * pow($windspeed, 0.16) + 0.4275 * $tempF * pow($windspeed, 0.16); $chillF = round($chillF); $chillC = round(($chillF - 32) / 1.8); $wxInfo['WIND CHILL'] = "$chillF°F ($chillC°C)"; } } } if (ereg('^(M?[0-9]{2})/(M?[0-9]{2}|[X]{2})?$',$part,$pieces)) { $tempC = (integer) strtr($pieces[1], 'M', '-'); $tempF = round(1.8 * $tempC + 32); $wxInfo['TEMP'] = "$tempF°F ($tempC°C)"; get_wind_chill($tempF, $wxInfo); if (strlen($pieces[2]) != 0 && $pieces[2] != 'XX') { $dewC = (integer) strtr($pieces[2], 'M', '-'); $dewF = round(1.8 * $dewC + 32); $wxInfo['DEWPT'] = "$dewF°F ($dewC°C)"; $rh = round(100 * pow((112 - (0.1 * $tempC) + $dewC) / (112 + (0.9 * $tempC)), 8)); $wxInfo['HUMIDITY'] = $rh . '%'; get_heat_index($tempF, $rh, $wxInfo); } $metarPtr++; $group++; } else { $group++; } } function get_altimeter($part, &$metarPtr, &$group, &$wxInfo) { // Decodes altimeter or barometer information. // Format is Annnn where nnnn represents a real number as nn.nn in inches of Hg, // or Qpppp where pppp = hectoPascals. // Some other common conversion factors: // 1 millibar = 1 hPa // 1 in Hg = 0.02953 hPa // 1 mm Hg = 25.4 in Hg = 0.750062 hPa // 1 lb/sq in = 0.491154 in Hg = 0.014504 hPa // 1 atm = 0.33421 in Hg = 0.0009869 hPa if (ereg('^(A|Q)([0-9]{4})',$part,$pieces)) { if ($pieces[1] == 'A') { $pressureIN = substr($pieces[2],0,2) . '.' . substr($pieces[2],2); // units are inches Hg $pressureHPA = round($pressureIN / 0.02953); // convert to hectoPascals } else { $pressureHPA = (integer) $pieces[2]; // units are hectoPascals $pressureIN = round(0.02953 * $pressureHPA,2); // convert to inches Hg } $wxInfo['BAROMETER'] = "$pressureHPA hPa ($pressureIN in Hg)"; $metarPtr++; $group++; } else { $group++; } } function print_wxInfo($wxInfo) { // Prints each piece of information stored in the array. // If an error occurs in retrieving a METAR file, check for index called 'ERROR'. // (Modify this function to fit your needs.) $dots = '...............'; foreach($wxInfo As $wxIndex => $wx) { if (strlen($wx) != 0) echo $wxIndex . substr($dots,0,strlen($dots)-strlen($wxIndex)) . " $wx
\n"; } } ?>