Nearby METAR decoded Name of station | town, nation | distance in miles | distance in km | compass direction | 'CYYZ' => 'Toronto Lester B Pearson International Airport|Ontario, Canada|104|167|ENE|', // lat=43.6667,long=-79.6167, elev=173, dated=24-MAY-17 'CYXU' => 'London Airport|Ontario, Canada|15|24|ENE|', // lat=43.0167,long=-81.1500, elev=278, dated=24-MAY-17 'KDTW' => 'Detroit/Wayne|Michigan, USA|109|175|WSW|', // lat=42.2333,long=-83.3333, elev=195, dated=24-MAY-17 'CYCK' => 'Chatham-Kent Municipal Airport|Chatham, Ontario, Canada|56|90|SW|', // lat=42.3000,long=-82.0833, elev=198, dated=24-MAY-17 'CYQG' => 'Windsor Airport|Ontario, Canada|91|147|WSW|', // lat=42.2667,long=-82.9667, elev=190, dated=24-MAY-17 # first five 'KDET' => 'Coleman A Young Municipal Airport (formerly Detroit City Airport until 2003)|Detroit, MI, USA|89|143|WSW|', // lat=42.4000,long=-83.0167, elev=190, dated=24-MAY-17 'CYZR' => 'Sarnia Airport|Ontario, Canada|44|71|W|', // lat=43.0000,long=-82.3000, elev=181, dated=24-MAY-17 'CWGD' => 'Goderich Automatic Weather Reporting System|Ontario, Canada|58|93|NNW|', // lat=43.7667,long=-81.7167, elev=214, dated=24-MAY-17 # (ICAO: CYGD) Goderich Airport, 'KPHN' => 'Port Huron|Michigan, USA|55|88|W|', // lat=42.9167,long=-82.5167, elev=198, dated=24-MAY-17 'CYHM' => 'John C Munro Hamilton International Airport|Ontario, Canada|77|124|ENE|', // lat=43.1667,long=-79.9333, elev=238, dated=24-MAY-17 'CYSN' => 'St. Catharines/Niagara District Airport|Niagara-on-the-Lake, Ontario, Canada|116|186|E|', // lat=43.2000,long=-79.1667, elev=98, dated=24-MAY-17 'KBUF' => 'Buffalo/Cheektow|New York, USA|137|220|E|', // lat=42.9333,long=-78.7333, elev=211, dated=24-MAY-17 'CXDI' => 'Delhi Aerodrome Cs (automatic)|Ontario, Canada|45|73|E|', // lat=42.8667,long=-80.5500, elev=231.7m, dated=24-MAY-17 'CYKF' => 'Region of Waterloo International Airport|Ontario, Canada|64|103|NE|', // lat=43.4667,long=-80.3833, elev=317, dated=24-MAY-17 'CXTO' => 'Toronto City Airport|Ontario, Canada|114|183|ENE|', // lat=43.6667,long=-79.4000, elev=113, dated=24-MAY-17 # first fifteen 'KMTC' => 'Selfridge Angb|Michigan, USA|74|119|WSW|', // lat=42.6167,long=-82.8167, elev=177, dated=24-MAY-17 'KBTP' => 'Butler Co.|Pennsylvania, USA|169|273|SSE|', // lat=40.7667,long=-79.9500, elev=380, dated=24-MAY-17 'KMNN' => 'Marion|Ohio, USA|182|293|SSW|', // lat=40.6167,long=-83.0667, elev=301, dated=24-MAY-17 'CWGL' => 'Lagoon City|Ontario, Canada|155|249|NE|', // Latitude 44.5167,long -79.2167, elev 221, dated 24/05/17 'CWLS' => 'Mount Forest(Mar|Ontario, Canada|78|125|NNE|', // Latitude 43.9667,long -80.7500, elev 415, dated 24/05/17 'CWMZ' => 'Western Isl Meteorological Aeronautical Presentation|Ontario, Canada|152|245|NNE|', // Latitude 45.0167,long -80.3667, elev 191, dated 24/05/17 'CWNC' => 'Cobourg (mars)|Ontario, Canada|178|286|ENE|', // Latitude 43.9500,long -78.1667, elev 78, dated 24/05/17 'CWPC' => 'Port Colborne(Au|Ontario, Canada|111|178|E|', // Latitude 42.8667,long -79.2500, elev 184, dated 24/05/17 'CWPS' => 'Long Point Meteorological Aeronautical Presentation|Ontario, Canada|76|122|ESE|', // Latitude 42.5667,long -80.0333, elev 175, dated 24/05/17 'CWWB' => 'Burlington Piers|Ontario, Canada|87|139|ENE|', // Latitude 43.3000,long -79.7833, elev 76, dated 24/05/17 'CWWX' => 'Cove Island Meteorological Aeronautical Presentation|Ontario, Canada|164|264|N|', // Latitude 45.3167,long -81.7333, elev 181, dated 24/05/17 'CWWZ' => 'Port Weller (mar|Ontario, Canada|114|183|ENE|', // Latitude 43.2500,long -79.2167, elev 79, dated 24/05/17 'CXBI' => 'Barrie-Oro|Ontario, Canada|141|228|NE|', // Latitude 44.4833,long -79.5500, elev 289, dated 24/05/17 ); /* 'CYXU' => 'London Airport|Ontario, Canada|15|24|ENE|', // lat=43.0167,long=-81.1500, elev=278, dated=24-MAY-17 'CYZR' => 'Sarnia Airport|Ontario, Canada|44|71|W|', // lat=43.0000,long=-82.3000, elev=181, dated=24-MAY-17 'CXDI' => 'Delhi Cs (automatic)|Ontario, Canada|45|73|E|', // lat=42.8667,long=-80.5500, elev=232, dated=24-MAY-17 'CWAJ' => 'Erieau (map|Ontario, Canada|54|87|SSW|', // lat=42.2500,long=-81.9000, elev=178, dated=24-MAY-17 'KPHN' => 'Port Huron|Michigan, USA|55|88|W|', // lat=42.9167,long=-82.5167, elev=198, dated=24-MAY-17 'CYCK' => 'Chatham|Ontario, Canada|56|90|SW|', // lat=42.3000,long=-82.0833, elev=198, dated=24-MAY-17 'CWGD' => 'Goderich (autob)|Ontario, Canada|58|93|NNW|', // lat=43.7667,long=-81.7167, elev=214, dated=24-MAY-17 'CYKF' => 'Waterloo Well|Ontario, Canada|64|103|NE|', // lat=43.4667,long=-80.3833, elev=317, dated=24-MAY-17 'CZEL' => 'Elora Rcs|Ontario, Canada|70|113|NE|', // lat=43.6500,long=-80.4167, elev=376, dated=24-MAY-17 'KMTC' => 'Selfridge Angb|Michigan, USA|74|119|WSW|', // lat=42.6167,long=-82.8167, elev=177, dated=24-MAY-17 'CWPS' => 'Long Point (map|Ontario, Canada|76|122|ESE|', // lat=42.5667,long=-80.0333, elev=175, dated=24-MAY-17 'CYHM' => 'Hamilton Airport|Ontario, Canada|77|124|ENE|', // lat=43.1667,long=-79.9333, elev=238, dated=24-MAY-17 'CWLS' => 'Mount Forest(Mar|Ontario, Canada|78|125|NNE|', // lat=43.9667,long=-80.7500, elev=415, dated=24-MAY-17 'CWWB' => 'Burlington Piers|Ontario, Canada|87|139|ENE|', // lat=43.3000,long=-79.7833, elev=76, dated=24-MAY-17 'KERI' => 'Erie|Pennsylvania, USA|88|141|SE|', // lat=42.0833,long=-80.1833, elev=222, dated=24-MAY-17 'KDET' => 'Detroit/City Air|Michigan, USA|89|143|WSW|', // lat=42.4000,long=-83.0167, elev=190, dated=24-MAY-17 'KLNN' => 'Willoughby|Ohio, USA|89|143|S|', // lat=41.6667,long=-81.3667, elev=191, dated=24-MAY-17 'KHZY' => 'Ashtabula|Ohio, USA|89|144|SSE|', // lat=41.7833,long=-80.7000, elev=276, dated=24-MAY-17 'CYQG' => 'Windsor Airport|Ontario, Canada|91|147|WSW|', // lat=42.2667,long=-82.9667, elev=190, dated=24-MAY-17 'KD95' => 'Lapeer|Michigan, USA|93|149|W|', // lat=43.0667,long=-83.2667, elev=255, dated=24-MAY-17 'KVLL' => 'Troy/Oakland|Michigan, USA|93|150|WSW|', // lat=42.5500,long=-83.1833, elev=222, dated=24-MAY-17 'KCGF' => 'Clevlnd/Cuyahoga|Ohio, USA|96|154|S|', // lat=41.5667,long=-81.4667, elev=268, dated=24-MAY-17 'KBAX' => 'Bad Axe|Michigan, USA|97|155|NW|', // lat=43.7833,long=-82.9833, elev=234, dated=24-MAY-17 'CXHA' => 'Harrow Cda|Ontario, Canada|98|158|SW|', // lat=42.0333,long=-82.9000, elev=191, dated=24-MAY-17 'KBKL' => 'Cleveland|Ohio, USA|99|159|S|', // lat=41.5333,long=-81.6667, elev=184, dated=24-MAY-17 'KP58' => 'Port Hope|Michigan, USA|100|162|NW|', // lat=44.0167,long=-82.8000, elev=179, dated=24-MAY-17 'KPTK' => 'Pontiac|Michigan, USA|102|165|W|', // lat=42.6667,long=-83.4167, elev=299, dated=24-MAY-17 'CXVN' => 'Vineland (au8)|Ontario, Canada|104|167|E|', // lat=43.1833,long=-79.4000, elev=79, dated=24-MAY-17 'CYYZ' => 'Toronto/Pearson|Ontario, Canada|104|167|ENE|', // lat=43.6667,long=-79.6167, elev=173, dated=24-MAY-17 'KONZ' => 'Detroit/Grosse I|Michigan, USA|105|170|SW|', // lat=42.1000,long=-83.1500, elev=180, dated=24-MAY-17 'KCFS' => 'Caro/Tuscola|Michigan, USA|107|173|WNW|', // lat=43.4667,long=-83.4500, elev=214, dated=24-MAY-17 'KCLE' => 'Cleveland|Ohio, USA|108|174|S|', // lat=41.4167,long=-81.8500, elev=233, dated=24-MAY-17 'KDTW' => 'Detroit/Wayne|Michigan, USA|109|175|WSW|', // lat=42.2333,long=-83.3333, elev=195, dated=24-MAY-17 'KGKJ' => 'Meadville|Pennsylvania, USA|110|178|SE|', // lat=41.6333,long=-80.2167, elev=428, dated=24-MAY-17 'CWPC' => 'Port Colborne(Au|Ontario, Canada|111|178|E|', // lat=42.8667,long=-79.2500, elev=184, dated=24-MAY-17 'CYTZ' => 'Toronto Il Vor|Ontario, Canada|113|181|ENE|', // lat=43.6333,long=-79.4000, elev=77, dated=24-MAY-17 'CWWZ' => 'Port Weller (mar|Ontario, Canada|114|183|ENE|', // lat=43.2500,long=-79.2167, elev=79, dated=24-MAY-17 'CXTO' => 'Toronto City|Ontario, Canada|114|183|ENE|', // lat=43.6667,long=-79.4000, elev=113, dated=24-MAY-17 'KDKK' => 'Dunkirk|New York, USA|114|183|ESE|', // lat=42.5000,long=-79.2833, elev=202, dated=24-MAY-17 'CYSN' => 'St. Catharines A|Ontario, Canada|116|186|E|', // lat=43.2000,long=-79.1667, elev=98, dated=24-MAY-17 'KFNT' => 'Flint|Michigan, USA|117|188|W|', // lat=42.9667,long=-83.7500, elev=233, dated=24-MAY-17 'KLPR' => 'Lorain/Elyria|Ohio, USA|117|189|SSW|', // lat=41.3500,long=-82.1833, elev=241, dated=24-MAY-17 'CYBN' => 'Borden|Ontario, Canada|118|190|NE|', // lat=44.2667,long=-79.9167, elev=223, dated=24-MAY-17 'KYIP' => 'Detroit/Willow|Michigan, USA|118|190|WSW|', // lat=42.2333,long=-83.5333, elev=215, dated=24-MAY-17 'KPOV' => 'Ravena/Portage|Ohio, USA|120|194|S|', // lat=41.2167,long=-81.2500, elev=365, dated=24-MAY-17 'CWCO' => 'Collingwood (aut|Ontario, Canada|121|195|NNE|', // lat=44.4500,long=-80.1667, elev=221, dated=24-MAY-17 'CXET' => 'Egbert Cs|Ontario, Canada|121|195|NE|', // lat=44.2333,long=-79.7833, elev=251, dated=24-MAY-17 'CYKZ' => 'Toronto Buttonvi|Ontario, Canada|121|195|ENE|', // lat=43.8667,long=-79.3667, elev=198, dated=24-MAY-17 'KTTF' => 'Monroe|Michigan, USA|123|198|SW|', // lat=41.9333,long=-83.4167, elev=188, dated=24-MAY-17 'KJHW' => 'Jamestown|New York, USA|124|200|ESE|', // lat=42.1333,long=-79.2667, elev=525, dated=24-MAY-17 'KYNG' => 'Youngstown|Ohio, USA|124|200|SSE|', // lat=41.2500,long=-80.6667, elev=360, dated=24-MAY-17 'CYVV' => 'Wiarton Air|Ontario, Canada|125|202|N|', // lat=44.7500,long=-81.0833, elev=222, dated=24-MAY-17 'KHYX' => 'Saginaw/Browne|Michigan, USA|127|204|WNW|', // lat=43.4333,long=-83.8667, elev=183, dated=24-MAY-17 'KIAG' => 'Niagara Falls|New York, USA|127|204|E|', // lat=43.1167,long=-78.9333, elev=182, dated=24-MAY-17 'KARB' => 'Ann Arbor|Michigan, USA|128|205|WSW|', // lat=42.2167,long=-83.7333, elev=251, dated=24-MAY-17 'KOZW' => 'Howell|Michigan, USA|130|210|W|', // lat=42.6167,long=-83.9667, elev=293, dated=24-MAY-17 'KAKR' => 'Akron (fulton)|Ohio, USA|133|214|S|', // lat=41.0333,long=-81.4667, elev=363, dated=24-MAY-17 'KFKL' => 'Franklin|Pennsylvania, USA|136|219|SE|', // lat=41.3667,long=-79.8667, elev=469, dated=24-MAY-17 'KRNP' => 'Owosso|Michigan, USA|136|220|W|', // lat=43.0000,long=-84.1333, elev=224, dated=24-MAY-17 'KBUF' => 'Buffalo/Cheektow|New York, USA|137|220|E|', // lat=42.9333,long=-78.7333, elev=211, dated=24-MAY-17 'KMBS' => 'Saginaw|Michigan, USA|139|224|WNW|', // lat=43.5333,long=-84.0833, elev=202, dated=24-MAY-17 'KCAK' => 'Akron|Ohio, USA|141|227|S|', // lat=40.9167,long=-81.4500, elev=377, dated=24-MAY-17 'KDUH' => 'Lambertville|Michigan, USA|141|227|SW|', // lat=41.7333,long=-83.6500, elev=204, dated=24-MAY-17 'CXBI' => 'Barrie-Oro|Ontario, Canada|141|228|NE|', // lat=44.4833,long=-79.5500, elev=289, dated=24-MAY-17 'KTDZ' => 'Toledo|Ohio, USA|142|228|SW|', // lat=41.5667,long=-83.4833, elev=189, dated=24-MAY-17 'KOSC' => 'Oscoda/Wurtsmith|Michigan, USA|143|229|NW|', // lat=44.4500,long=-83.4000, elev=193, dated=24-MAY-17 'KUCP' => 'New Castle Muni|Pennsylvania, USA|143|230|SSE|', // lat=41.0333,long=-80.4167, elev=327, dated=24-MAY-17 'CYOO' => 'Oshawa|Ontario, Canada|144|231|ENE|', // lat=43.9167,long=-78.9000, elev=139, dated=24-MAY-17 'KBJJ' => 'Wooster|Ohio, USA|146|235|S|', // lat=40.8667,long=-81.8833, elev=343, dated=24-MAY-17 'KIKW' => 'Midland Barstow|Michigan, USA|151|242|WNW|', // lat=43.6667,long=-84.2667, elev=194, dated=24-MAY-17 'CWMZ' => 'Western Isl (map|Ontario, Canada|152|245|NNE|', // lat=45.0167,long=-80.3667, elev=191, dated=24-MAY-17 'KTEW' => 'Mason|Michigan, USA|154|247|W|', // lat=42.5667,long=-84.4167, elev=280, dated=24-MAY-17 'KTOL' => 'Toledo|Ohio, USA|154|247|SW|', // lat=41.5833,long=-83.8000, elev=210, dated=24-MAY-17 'CWGL' => 'Lagoon City|Ontario, Canada|155|249|NE|', // lat=44.5167,long=-79.2167, elev=221, dated=24-MAY-17 'KADG' => 'Adrian|Michigan, USA|155|249|WSW|', // lat=41.8667,long=-84.0833, elev=241, dated=24-MAY-17 'KMFD' => 'Mansfield|Ohio, USA|158|254|SSW|', // lat=40.8167,long=-82.5167, elev=395, dated=24-MAY-17 'KLAN' => 'Lansing|Michigan, USA|160|257|W|', // lat=42.7833,long=-84.5833, elev=264, dated=24-MAY-17 'KBVI' => 'Beaver Falls Arp|Pennsylvania, USA|160|258|SSE|', // lat=40.7667,long=-80.4000, elev=382, dated=24-MAY-17 'KJXN' => 'Jackson/Reynolds|Michigan, USA|161|260|WSW|', // lat=42.2667,long=-84.4667, elev=305, dated=24-MAY-17 'KBFD' => 'Bradford|Pennsylvania, USA|164|263|ESE|', // lat=41.8000,long=-78.6333, elev=647, dated=24-MAY-17 'CWWX' => 'Cove Island (map|Ontario, Canada|164|264|N|', // lat=45.3167,long=-81.7333, elev=181, dated=24-MAY-17 'KOLE' => 'Olean|New York, USA|164|264|ESE|', // lat=42.2333,long=-78.3667, elev=651, dated=24-MAY-17 'KY31' => 'West Branch|Michigan, USA|164|264|NW|', // lat=44.2500,long=-84.1833, elev=270, dated=24-MAY-17 'KAMN' => 'Alma|Michigan, USA|166|267|W|', // lat=43.3167,long=-84.6833, elev=230, dated=24-MAY-17 'KUSE' => 'Wauseon|Ohio, USA|166|267|WSW|', // lat=41.6167,long=-84.1333, elev=238, dated=24-MAY-17 'KBTP' => 'Butler Co.|Pennsylvania, USA|169|273|SSE|', // lat=40.7667,long=-79.9500, elev=380, dated=24-MAY-17 'KMOP' => 'Mount Pleasant|Michigan, USA|172|277|WNW|', // lat=43.6167,long=-84.7333, elev=230, dated=24-MAY-17 'KPHD' => 'New Philadelphia| Ohio, USA|172|277|S|', // lat=40.4667,long=-81.4167, elev=272, dated=24-MAY-17 'KFPK' => 'Charlotte|Michigan, USA|174|279|W|', // lat=42.5667,long=-84.8167, elev=272, dated=24-MAY-17 'CYQA' => 'Muskoka Airport|Ontario, Canada|175|282|NE|', // lat=44.9667,long=-79.2833, elev=282, dated=24-MAY-17 'KJYM' => 'Hillsdale|Michigan, USA|176|283|WSW|', // lat=41.9167,long=-84.5833, elev=360, dated=24-MAY-17 'KFDY' => 'Findlay|Ohio, USA|176|284|SW|', // lat=41.0167,long=-83.6667, elev=247, dated=24-MAY-17 'CYPQ' => 'Peterborough Arp|Ontario, Canada|177|284|ENE|', // lat=44.2167,long=-78.3667, elev=191, dated=24-MAY-17 'CWNC' => 'Cobourg (mars)|Ontario, Canada|178|286|ENE|', // lat=43.9500,long=-78.1667, elev=78, dated=24-MAY-17 'CXPC' => 'Parry Sound|Ontario, Canada|179|288|NNE|', // lat=45.3500,long=-80.0500, elev=176, dated=24-MAY-17 'KDUJ' => 'Du Bois|Pennsylvania, USA|179|289|SE|', // lat=41.1667,long=-78.9000, elev=554, dated=24-MAY-17 'KAPN' => 'Alpena|Michigan, USA|180|290|NW|', // lat=45.0667,long=-83.5667, elev=210, dated=24-MAY-17 'KPIT' => 'Pittsburgh|Pennsylvania, USA|180|290|SSE|', // lat=40.5000,long=-80.2667, elev=357, dated=24-MAY-17 'KMNN' => 'Marion|Ohio, USA|182|293|SSW|', // lat=40.6167,long=-83.0667, elev=301, dated=24-MAY-17 'KY70' => 'Ionia| Michigan, USA|184|296|W|', // lat=42.9333,long=-85.0667, elev=250, dated=24-MAY-17 // Note: only first 100 closest METARs of 174 found within 250 miles are shown // list generated Wed, 08-Nov-2017 5:26pm PST at http://saratoga-weather.org/wxtemplates/find-metar.php */ /* The list generated from http://saratoga-weather.org/wxtemplates/find-metar-100.php#findmetar is $MetarList. Use $icaoIdArray = array(); for ($i=0; $i 'fetch_metar.php' script running find-aerodrome function returned=" . $place['name'] . "
"; return $place; } //========================================================================================== # The following 2 functions are mainly copied from those of same names in Ken True's Saratoga # "metar-display package (V1.02 - 11-Oct-2017)\get-metar-conditions-inc.php". # The difference is that the second function includes code from Version 1.14 - 23-May-2016 # "metar-display\get-metar-conditions-inc.php" for old PHP versions and it has # been modified so that it only returns the content, while the original returns header and content. // ------------------------------------------------------------------ function mtr_fetch_microtime() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } // ------------------------------------------------------------------ function mtr_fetchUrlWithoutHanging($url, $useFopen=false) { //----------------------------------------------------------------- // Function to fetch file from a URL (the file fetched is the METAR) //----------------------------------------------------------------- // get contents from one URL and return as string global $Debug, $needCookie, $show_diagnostics; # Last variable added, not in original $overall_start = time(); if (!$useFopen) { // Set maximum number of seconds (can have floating-point) to wait for feed before displaying page without feed $numberOfSeconds = 6; // Thanks to Curly from ricksturf.com for the cURL fetch functions $data = ''; $domain = parse_url($url, PHP_URL_HOST); $theURL = str_replace('nocache', '?' . $overall_start, $url); // add cache-buster to URL if needed $Debug.= "\n"; $ch = curl_init(); // initialize a cURL session curl_setopt($ch, CURLOPT_URL, $theURL); // connect to provided URL curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // don't verify peer certificate curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (get-metar-conditions-inc.php - saratoga-weather.org)'); curl_setopt($ch, CURLOPT_HTTPHEADER, // request LD-JSON format array( "Accept: text/html,text/plain" )); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $numberOfSeconds); // connection timeout curl_setopt($ch, CURLOPT_TIMEOUT, $numberOfSeconds); // data timeout curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return the data transfer curl_setopt($ch, CURLOPT_NOBODY, false); // set nobody curl_setopt($ch, CURLOPT_HEADER, true); // include header information // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // follow Location: redirect // curl_setopt($ch, CURLOPT_MAXREDIRS, 1); // but only one time if (isset($needCookie[$domain])) { curl_setopt($ch, $needCookie[$domain]); // set the cookie for this request curl_setopt($ch, CURLOPT_COOKIESESSION, true); // and ignore prior cookies $Debug.= "\n"; } $data = curl_exec($ch); // execute session if (curl_error($ch) <> '') { // IF there is an error $Debug.= "\n"; // display error notice } $cinfo = curl_getinfo($ch); // get info on curl exec. /* curl info sample Array ( [url] => http://saratoga-weather.net/clientraw.txt [content_type] => text/plain [http_code] => 200 [header_size] => 266 [request_size] => 141 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.125 [namelookup_time] => 0.016 [connect_time] => 0.063 [pretransfer_time] => 0.063 [size_upload] => 0 [size_download] => 758 [speed_download] => 6064 [speed_upload] => 0 [download_content_length] => 758 [upload_content_length] => -1 [starttransfer_time] => 0.125 [redirect_time] => 0 [redirect_url] => [primary_ip] => 74.208.149.102 [certinfo] => Array ( ) [primary_port] => 80 [local_ip] => 192.168.1.104 [local_port] => 54156 ) */ $Debug.= "\n"; // $Debug .= "\n"; curl_close($ch); // close the cURL session // $Debug .= "\n"; $i = strpos($data, "\r\n\r\n"); $headers = substr($data, 0, $i); $content = substr($data, $i + 4); if ($cinfo['http_code'] <> '200') { $Debug.= "\n"; } if($show_diagnostics) echo $Debug; # This line added, not in original return $content; # The original returned both $content and $headers }else { $T_start = mtr_fetch_microtime(); $xml = array(); $handle = fopen($url, "r"); if ($handle) { while (($buffer = fgets($handle, 4096)) !== false) { $xml[] = $buffer; } if (!feof($handle)) { echo "Error: unexpected fgets() fail\n"; } fclose($handle); } /* // print "\n"; $STRopts = array( 'http' => array( 'method' => "GET", 'protocol_version' => 1.1, 'header' => "Cache-Control: no-cache, must-revalidate\r\n" . "Cache-control: max-age=0\r\n" . "Connection: close\r\n" . "User-agent: Mozilla/5.0 (get-metar-conditions-inc.php - saratoga-weather.org)\r\n" . "Accept: text/html,text/plain\r\n" ) , 'https' => array( 'method' => "GET", 'protocol_version' => 1.1, 'header' => "Cache-Control: no-cache, must-revalidate\r\n" . "Cache-control: max-age=0\r\n" . "Connection: close\r\n" . "User-agent: Mozilla/5.0 (get-metar-conditions-inc.php - saratoga-weather.org)\r\n" . "Accept: text/html,text/plain\r\n" ) ); $STRcontext = stream_context_create($STRopts); $xml = file_get_contents($url, false, $STRcontext); $T_close = mtr_fetch_microtime(); $headerarray = get_headers($url, 0); $theaders = join("\r\n", $headerarray); $xml = $theaders . "\r\n\r\n" . $xml; $ms_total = sprintf("%01.3f", round($T_close - $T_start, 3)); $Debug.= "\n"; $Debug.= "<-- get_headers returns\n" . $theaders . "\n -->\n"; // print " file() stats: total=$ms_total secs.\n"; $overall_end = time(); $overall_elapsed = $overall_end - $overall_start; $Debug.= "\n"; // print "fetch function elapsed= $overall_elapsed secs.\n"; */ return ($xml); } } // end mtr_fetchUrlWithoutHanging // ------------------------------------------------------------------ //----------------------------------------------------------------- // Function to insert decoded METAR text as contents into table //----------------------------------------------------------------- function novel_disp_table($input) // Novel to SPAWS { global $icaoIdArray, $compass_expanded; // Array with aerodrome names and distances, array with compass direction names in full if(!isset($input['GroupCount']['STANDARD']) and $input['GroupCount']['STANDARD']) { echo "No METAR information available
"; // Useful Message might be in $input['Info']['FEEDBACK'], but safer to ignore that for production system return; } ######################################### # Start of SPAWS novel snippet of # # code to gather information from # # present weather and cloud cover # # Groups to select suitable icon # ######################################### $condIconDir = 'metar-images/'; // Directory with condition icons mtr_load_iconDefs(); // array of condition icon file names if (isset($input['Info']['CONDITIONS']) and $input['GroupProcessed']['CONDITIONS'] != '//') $Weather = $input['Info']['CONDITIONS']; else $Weather = ''; $CloudDetails = isset($input['Info']['CLOUDS']) ? trim($input['Info']['CLOUDS']) : ''; $Conds = $Weather; $condwords = $Weather; if ($CloudDetails <> '' and $Weather <> '') {// Choose any conditions report first $condwords = $Weather . ", " . $CloudDetails; // append a cloud details descriptor if available $Conds = $Weather . ", " . $CloudDetails; } if ($Weather == '' and $CloudDetails <> '') { $condwords = $CloudDetails; // no weather conditions .. use cloud details only $Conds = $CloudDetails; } if ($condwords == '') { $condwords = "Cloud and Visibility OK"; $Conds = "No significant clouds"; // e.g. Stansted report SA 22/10/2017 07:50-> METAR EGSS 220750Z AUTO 26012KT 9999 NCD 10/05 Q1009= } $icon_num = rev_get_iconnumber(strtolower($condwords)); $icon_img = newIcon($icon_num); #################################### # End of SPAWS novel snippet # #################################### echo "\n"; if(array_key_exists('Feedback', $input['Info']) ) echo ""; echo ""; /* if(array_key_exists('ISSUED', $input['Info'])) { echo ""; } */ $place = find_aerodrome($input['Info']['STATION']); echo ""; echo ""; if(count($place) > 1) { echo ""; echo ""; } if(array_key_exists('LOCAL', $input['Info'])) { echo ""; echo ""; } if(array_key_exists('COR', $input['Info'])) { echo ""; echo ""; } echo ""; ####################################### echo ""; ############################################## # Table rows are optional, appearing # # if array element exists or count is # # numerical and greater than zero # ############################################## if(array_key_exists('COLOUR0', $input['Info']) ) { echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('CONDITIONS',$input['Info'])) { // Present Weather echo "\n"; echo ""; echo "\n\n"; } if(isset($input['Info']['WINDMPH'])) { echo "\n \n"; echo ""; echo "\n\n"; } if(array_key_exists('DIRECTION',$input['Info']) ){ echo "\n"; echo "\n\n"; } if(array_key_exists('SPEED',$input['Info']) ){ echo "\n"; echo ''; if(array_key_exists('KNOTS', $input['Info']) and array_key_exists('WINDMPH', $input['Info']) and $input['Info']['WINDMPH'] > 0) echo ''; else echo ''; echo "\n\n"; } if(array_key_exists('GUST',$input['Info']) ){ echo "\n"; echo ''; echo ''; echo "\n\n"; } // CLOUD OUTPUT $skyString = ""; $skyIterator = 0; if(array_key_exists('SKY', $input['GroupProcessed']) ) {// Summary of sky conditions while(array_key_exists('$skyIterator', $input['GroupProcessed']['SKY']) and $skyIterator < $input['GroupCount']['SKY']) { $skyIterator++; $skyString .= $input['GroupProcessed']['SKY'][$skyIterator] . " "; } echo "\n"; echo ""; } if(array_key_exists('CEILING',$input['Info']) ) {// The height above ground or water of the base of the lowest layer of cloud where the summation amount exceeds half the sky echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('CLOUD-DETAILS',$input['Info']) ) { // Specify cloud layers echo "\n"; echo ""; echo "\n\n"; } // VISIBILITY OUTPUT if(array_key_exists('VISIBILITY',$input['Info']) ) { // Prevailing visibility echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('MINIMUM',$input['Info']) ) { // Minimum Directional visibility echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('RVR',$input['GroupCount']) and $input['GroupCount']['RVR'] > 0 ) { // Runway visibility echo "\n"; echo ""; echo "\n\n"; } // TEMPERATURE OUTPUT if(array_key_exists('TEMP',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('HEAT INDEX',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('HUMIDEX',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('APPARENT',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('WIND CHILL',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('DEWPT',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('ABS_HUMIDITY',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('REL_HUMIDITY',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } // PRESSURE OUTPUT // The following code snippet was added January 2018 if(array_key_exists('SLP',$input['Info']) ) { echo "\n"; echo ""; echo ""; echo "\n\n"; } // End of code snippet added January 2018 if(array_key_exists('BAROMETER',$input['Info']) ){ echo "\n"; echo ""; echo ""; echo "\n\n"; } if(isset($pressureHPA) and isset($tempC) and isset($dewC)){ calculate_wet_bulb_temperature($tempC,$dewC,$pressureHPA); echo "\n"; echo ""; echo ""; echo "\n\n"; } // SUPPLEMENTARY OUTPUT if(array_key_exists('WIND_SHEAR',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('SEA_S',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('RECENT',$input['GroupCount']) and $input['GroupCount']['RECENT'] > 0 ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('RUNWAY',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('TREND_TYPE',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('CHANGE',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; } if(array_key_exists('STATE2',$input['Info']) ){ echo "\n"; echo ""; echo "\n\n"; unset($input['Info']['COLOUR2']); echo "\n"; echo ""; echo "\n\n"; } /* if(array_key_exists('REMARK',$input['GroupProcessed']) and array_key_exists(0, $input['GroupProcessed']['REMARK'])) { echo "\n"; echo ''; echo "\n\n"; } */ if(array_key_exists('REMARK',$input['Info']) and array_key_exists(1,$input['Info']['REMARK'])) { echo "\n"; echo ''; echo "\n\n"; } // End of snippet amended in January and February 2018 echo "
" . $input['Info']['Feedback'] . "
Issued '" . $input['Info']['ISSUED'] . " GMT'
" . $place['name'] . " (station id=" . $place['icao'] . ") " . $place['nation'] . "

" . 'Distance from station' . ": "; echo $place['compass'] . " "; echo $place['miles'] . " mi, "; echo $place['kilometres'] . " km
METAR Report issued " . $input['Info']['LOCAL'] . ' by ' . $input['Info']['BY'] . "
" . $input['Info']['COR'] . "
" . $input['Info']['METAR'] . "
ParameterValue
Present Colour State (Visibility and Cloud ceiling summary)" . $input['Info']['COLOUR0'] . $input['Info']['STATE0'] . "
Present Weather" . $input['Info']['CONDITIONS'] . "
"; ?> <?php  echo $condIconDir . $icon_img . " height="58" width="55" />

"; if(isset($input['Info']['FROM']) ) { echo "picture to indicate from wind direction"; } echo "picture with compass to indicate dominate wind direction"; if(isset($input['Info']['TO'])) { echo "picture to indicate to wind direction"; } ?>
Wind Direction range" . $input['Info']['VARIABLE'] . "
Average wind direction"; if(array_key_exists('BEARING',$input['Info'])) echo $input['Info']['BEARING'] . " = "; $direction = trim($input['Info']['DIRECTION']); echo $compass_expanded[$direction] . "
Average Wind in
last ten minutes
' . $input['Info']['KNOTS'] . ' knots, ' . $input['Info']['WINDMPH'] . ' mph, ' . $input['Info']['WINDMPS'] . ' m s -1' . $input['Info']['SPEED'] . '
Wind Gust in
last ten minutes
' . $input['Info']['GUST'] . '
Sky" . $input['Info']['SKY'] . "
Cloud Ceiling" . $input['Info']['CEILING'] . "
Observed clouds
(" . $input['GroupCount']['SKY'] . " report"; echo $input['GroupCount']['SKY'] == 1 ? "" : "s"; echo ")
" . $input['Info']['CLOUD-DETAILS'] . "
Prevailing Visibility" . $input['Info']['VISIBILITY'] . "
Minimum Directional Visibility" . $input['Info']['MINIMUM'] . "
Runway Visual Range (" . $input['GroupCount']['RVR'] . " reports)" . $input['Info']['RVR'] . "
Temperature" . $input['Info']['TEMP'] . "
Calculated USA Heat Index" . $input['Info']['HEAT INDEX'] . "
Calculated Canadian Humidity Index" . $input['Info']['HUMIDEX'] . "
Calculated Australian
Apparent Temperature
" . $input['Info']['APPARENT'] . "
Calculated Wind Chill" . $input['Info']['WIND CHILL'] . "
Dew point" . $input['Info']['DEWPT'] . "
Calculated Absolute Humidity" . $input['Info']['ABS_HUMIDITY'] . " g m-3
Calculated Relative Humidity" . $input['Info']['REL_HUMIDITY'] . " %
Air Pressure (Corrected to sea level)" . $input['Info']['SLP'] . "
" . $input['GroupCount']['BAROMETER'] . "" . $input['Info']['BAROMETER'] . "
Calculated Wet Bulb temperature" . $input['Info']['WET_BULB'] . "
Wind Shear" . $input['Info']['WIND_SHEAR'] . "
Sea report" . $input['Info']['SEA_S'] . "
Since the previous observation (but not at present),
the following " . $input['GroupCount']['RECENT'] . " meteorological phenomena were observed
" . $input['Info']['RECENT'] . "
Runway state report" . $input['Info']['RUNWAY'] . "
Forecast trends exist?" . $input['Info']['TREND_TYPE'] . "
Forecast trends details" . $input['Info']['CHANGE'] . "
Forecast Colour State (summarising worst of Visibility and Cloud ceiling)" . $input['Info']['COLOUR2'] . "
Decoding colour as Aerodrome Forecast Fitness State" . $input['Info']['STATE2'] . "
Remarks (sources)'; if(array_key_exists('single', $input['GroupCount']) and $input['GroupCount']['single'] > 0) echo "" . $input['GroupCount']['single'] . ' (single segment not country-specific) matches from array_walk
'; if(array_key_exists('common', $input['GroupCount']) and $input['GroupCount']['common'] > 0) echo "" . $input['GroupCount']['common'] . ' (multiple segments not country-specific) matches from general
'; if(array_key_exists('Australian', $input['GroupCount']) and $input['GroupCount']['Australian'] > 0) echo "" . $input['GroupCount']['Australian'] . ' matches specific to Australian guide
'; if(array_key_exists('Canada', $input['GroupCount']) and $input['GroupCount']['Canada'] > 0 || $input['GroupCount']['CanadaWalk'] > 0 ) echo "" . $input['GroupCount']['CanadaWalk'] . ' (single segment) and ' . $input['GroupCount']['Canada'] . ' (multiple segments) matches specific to Canadian MANOBS
'; if(array_key_exists('Italian', $input['GroupCount']) and $input['GroupCount']['Italian'] > 0) echo "" . $input['GroupCount']['Italian'] . ' matches specific to Italian usage
'; if(array_key_exists('NZ', $input['GroupCount']) and $input['GroupCount']['NZ'] > 0) echo "" . $input['GroupCount']['NZ'] . ' matches specific to New Zealand reports
'; if(array_key_exists('USAF', $input['GroupCount']) and $input['GroupCount']['USAF'] > 0) echo "" . $input['GroupCount']['USAF'] . ' (multiple segments) matches associated with U.S. Air Force
'; if(array_key_exists('USA_walk', $input['GroupCount']) and $input['GroupCount']['USA_walk'] > 0 ) echo "" . $input['GroupCount']['USA_walk'] . ' (single segment) matches associated with U.S. Air Force
'; if(array_key_exists('FAA', $input['GroupCount']) and $input['GroupCount']['FAA'] > 0) echo "" . ($input['GroupCount']['FAA'] - $input['GroupCount']['USAF']) . ' (multiple segments) of matches only associated with Federal Meteorological Handbook No. 1 or known extras
'; echo '
' . $input['Info']['REMARK'][0] . '
    '; for($i =1; $i < count($input['Info']['REMARK']); $i++ ) { if(substr($input['Info']['REMARK'] [$i], 0, 1) == '<') echo "

    " . $input['Info']['REMARK'] [$i] . "

    "; // footnotes else echo "
  1. " . $input['Info']['REMARK'] [$i] . "
  2. "; // bullets } echo '
\n"; } //========================================================================================== # The following 3 functions are copied (with 3 lines re $Condstring changed in 2nd) # from "metar-display package (V1.02 - 11-Oct-2017)" from saratoga-weather.org # "get-metar-conditions-inc(Version 1.16 - 11-Oct-2017).php" and # "include-metar-display(Version 1.06 - 29-Nov-2011).php" // ------------------------------------------------------------------ function mtr_load_iconDefs() { global $Icons, $IconsLarge, $IconsText, $Conditions, $Debug; // CURRENT CONDITIONS ICONS FOR clientraw.txt // create array for icons. There are 35 possible values in clientraw.txt // It would be simpler to do this with array() but to make it easier to // modify each element is defined individually. Each index [#] corresponds // to the value provided in clientraw.txt $Icons[0] = "day_clear.gif"; // image sunny.visible $Icons[1] = "night_clear.gif"; // image clearnight.visible $Icons[2] = "day_partly_cloudy.gif"; // image cloudy.visible $Icons[3] = "day_partly_cloudy.gif"; // image cloudy2.visible $Icons[4] = "night_partly_cloudy.gif"; // image night cloudy.visible $Icons[5] = "day_clear.gif"; // image dry.visible $Icons[6] = "fog.gif"; // image fog.visible $Icons[7] = "haze-sm.gif"; // image haze.visible $Icons[8] = "day_heavy_rain.gif"; // image heavyrain.visible $Icons[9] = "day_mostly_sunny.gif"; // image mainlyfine.visible $Icons[10] = "mist-sm.gif"; // image mist.visible $Icons[11] = "fog.gif"; // image night fog.visible $Icons[12] = "night_heavy_rain.gif"; // image night heavyrain.visible $Icons[13] = "night_cloudy.gif"; // image night overcast.visible $Icons[14] = "night_rain.gif"; // image night rain.visible $Icons[15] = "night_light_rain.gif"; // image night showers.visible $Icons[16] = "night_snow.gif"; // image night snow.visible $Icons[17] = "night_tstorm.gif"; // image night thunder.visible $Icons[18] = "day_cloudy.gif"; // image overcast.visible $Icons[19] = "day_partly_cloudy.gif"; // image partlycloudy.visible $Icons[20] = "day_rain.gif"; // image rain.visible $Icons[21] = "day_rain.gif"; // image rain2.visible $Icons[22] = "day_light_rain.gif"; // image showers2.visible $Icons[23] = "sleet.gif"; // image sleet.visible $Icons[24] = "sleet.gif"; // image sleetshowers.visible $Icons[25] = "day_snow.gif"; // image snow.visible $Icons[26] = "day_snow.gif"; // image snowmelt.visible $Icons[27] = "day_snow.gif"; // image snowshowers2.visible $Icons[28] = "day_clear.gif"; // image sunny.visible $Icons[29] = "day_tstorm.gif"; // image thundershowers.visible $Icons[30] = "day_tstorm.gif"; // image thundershowers2.visible $Icons[31] = "day_tstorm.gif"; // image thunderstorms.visible $Icons[32] = "tornado.gif"; // image tornado.visible $Icons[33] = "windy-sm.gif"; // image windy.visible $Icons[34] = "day_partly_cloudy.gif"; // stopped rainning $Icons[35] = "windyrain-sm.gif"; // wind + rain $IconsText[0] = 'Sunny'; $IconsText[1] = 'Clear'; $IconsText[2] = 'Cloudy'; $IconsText[3] = 'Cloudy2'; $IconsText[4] = 'Partly Cloudy'; $IconsText[5] = 'Dry'; $IconsText[6] = 'Fog'; $IconsText[7] = 'Haze'; $IconsText[8] = 'Heavy Rain'; $IconsText[9] = 'Mainly Fine'; $IconsText[10] = 'Mist'; $IconsText[11] = 'Fog'; $IconsText[12] = 'Heavy Rain'; $IconsText[13] = 'Overcast'; $IconsText[14] = 'Rain'; $IconsText[15] = 'Showers'; $IconsText[16] = 'Snow'; $IconsText[17] = 'Thunder'; $IconsText[18] = 'Overcast'; $IconsText[19] = 'Partly Cloudy'; $IconsText[20] = 'Rain'; $IconsText[21] = 'Rain2'; $IconsText[22] = 'Showers2'; $IconsText[23] = 'Sleet'; $IconsText[24] = 'Sleet Showers'; $IconsText[25] = 'Snow'; $IconsText[26] = 'Snow Melt'; $IconsText[27] = 'Snow Showers2'; $IconsText[28] = 'Sunny'; $IconsText[29] = 'Thunder Showers'; $IconsText[30] = 'Thunder Showers2'; $IconsText[31] = 'Thunder Storms'; $IconsText[32] = 'Tornado'; $IconsText[33] = 'Windy'; $IconsText[34] = 'Stopped Raining'; $IconsText[35] = 'Wind/Rain'; $IconsLarge = array( "skc.jpg", // 0 imagesunny.visible "nskc.jpg", // 1 imageclearnight.visible "bkn.jpg", // 2 imagecloudy.visible "sct.jpg", // 3 imagecloudy2.visible "nbkn.jpg", // 4 imagecloudynight.visible "sct.jpg", // 5 imagedry.visible "fg.jpg", // 6 imagefog.visible "hazy.jpg", // 7 imagehaze.visible "ra.jpg", // 8 imageheavyrain.visible "few.jpg", // 9 imagemainlyfine.visible "mist.jpg", // 10 imagemist.visible "nfg.jpg", // 11 imagenightfog.visible "nra.jpg", // 12 imagenightheavyrain.visible "novc.jpg", // 13 imagenightovercast.visible "nra.jpg", // 14 imagenightrain.visible SAME AS EARLIER "nshra.jpg", // 15 imagenightshowers.visible "nsn.jpg", // 16 imagenightsnow.visible "ntsra.jpg", // 17 imagenightthunder.visible "ovc.jpg", // 18 imageovercast.visible "sct.jpg", // 19 imagepartlycloudy.visible "ra.jpg", // 20 imagerain.visible SAME AS EARLIER "ra.jpg", // 21 imagerain2.visible SAME AS PREVIOUS "shra.jpg", // 22 imageshowers2.visible "ip.jpg", // 23 imagesleet.visible "ip.jpg", // 24 imagesleetshowers.visible SAME AS PREVIOUS "sn.jpg", // 25 imagesnow.visible "sn.jpg", // 26 imagesnowmelt.visible SAME AS PREVIOUS "sn.jpg", // 27 imagesnowshowers2.visible "skc.jpg", // 28 imagesunny.visible "scttsra.jpg", // 29 imagethundershowers.visible "hi_tsra.jpg", // 30 imagethundershowers2.visible "tsra.jpg", // 31 imagethunderstorms.visible "nsvrtsra.jpg", // 32 imagetornado.visible "wind.jpg", // 33 imagewindy.visible "ra1.jpg", // 34 stopped rainning "windyrain.jpg" // 35 windy/rain ); /* the following is a lookup table for conditions text from the metar to return the WD Icon number above. It is sorted such that the most severe conditions are at the top of the list, with least severe at the bottom. This is done so that significant weather icon will prevail when multiple conditions/sky cover messages are emitted by the METAR station. tornado/waterspout thunder (in any form) Ice / Snow/ Freezing / Sleet Rain Fog Haze/Smoke/Dust/Volcano cloud cover */ $Condstring = ' # cond|tornado|32|32|Severe storm| cond|thunder|31|17|Thunder storm| cond|ice|23|23|Sleet| cond|snow|25|16|Snow| cond|freezing rain|23|23|FrzgRn| cond|freezing drizzle|23|23|FrzgRn| cond|freezing fog|6|11|FrzgFog| cond|hail|23|23|Hail| cond|heavy rain|8|12|Rain| cond|light rain|22|15|Rain| cond|showers|22|15|Showers| cond|rain|20|14|Rain| cond|fog|6|11|Fog| cond|drizzle|22|15|Drizzle| cond|mist|10|10|Mist| cond|haze|7|7|Haze| cond|dust|7|7|Dust| cond|smoke|7|7|Smoke| cond|volcanic|7|7|Volcanic Ash| cond|sand|7|7|Sand| cond|overcast|18|18|Overcast| cond|5-7|2|4|Mostly Cloudy| cond|3-4|19|4|Partly Cloudy| cond|1-2|9|4|Few Clouds| cond|no|0|1|Clear| cond|clear|0|1|Clear| cond|cloudy|19|4|Variable Clouds| # '; $config = explode("\n", $Condstring); foreach($config as $key => $rec) { // load the parser condition strings $recin = trim($rec); if ($recin and substr($recin, 0, 1) <> '#') { // got a non comment record list($type, $keyword, $dayicon, $nighticon, $condition) = explode('|', $recin . '|||||'); if (isset($type) and strtolower($type) == 'cond' and isset($condition)) { $Conditions["$keyword"] = "$dayicon\t$nighticon\t$condition"; } } // end if not comment or blank } // end loading of loop over config records return; } //========================================================================= // pick the NOAA style condition icon based on icon number function newIcon($numb) { global $condIconDir,$condIconType; $iconList = array( "skc.jpg", // 0 imagesunny.visible "nskc.jpg", // 1 imageclearnight.visible "bkn.jpg", // 2 imagecloudy.visible "sct.jpg", // 3 imagecloudy2.visible "nbkn.jpg", // 4 imagecloudynight.visible "sct.jpg", // 5 imagedry.visible "fg.jpg", // 6 imagefog.visible "hazy.jpg", // 7 imagehaze.visible "ra.jpg", // 8 imageheavyrain.visible "few.jpg", // 9 imagemainlyfine.visible "mist.jpg", // 10 imagemist.visible "nfg.jpg", // 11 imagenightfog.visible "nra.jpg", // 12 imagenightheavyrain.visible "novc.jpg", // 13 imagenightovercast.visible "nra.jpg", // 14 imagenightrain.visible "nshra.jpg", // 15 imagenightshowers.visible "nsn.jpg", // 16 imagenightsnow.visible "ntsra.jpg", // 17 imagenightthunder.visible "ovc.jpg", // 18 imageovercast.visible "sct.jpg", // 19 imagepartlycloudy.visible "ra.jpg", // 20 imagerain.visible "ra.jpg", // 21 imagerain2.visible "shra.jpg", // 22 imageshowers2.visible "ip.jpg", // 23 imagesleet.visible "ip.jpg", // 24 imagesleetshowers.visible "sn.jpg", // 25 imagesnow.visible "sn.jpg", // 26 imagesnowmelt.visible "sn.jpg", // 27 imagesnowshowers2.visible "skc.jpg", // 28 imagesunny.visible "scttsra.jpg", // 29 imagethundershowers.visible "hi_tsra.jpg", // 30 imagethundershowers2.visible "tsra.jpg", // 31 imagethunderstorms.visible "nsvrtsra.jpg", // 32 imagetornado.visible "wind.jpg", // 33 imagewindy.visible "ra1.jpg", // 34 stopped rainning "windyrain.jpg" // 35 windy/rain ); $tempicon = $iconList[$numb]; return($tempicon); } // ------------------------------------------------------------------ function rev_get_iconnumber($condString) { global $Icons, $IconsText, $Conditions; if (1) { $daynight = 'day'; }else{ $daynight = 'night'; } $condString = trim($condString); reset($Conditions); // Do search in load order $iconnumb = 5; // default is a sunny icon // scan over the conditions table and see if an icon fits the description in the table foreach($Conditions as $cond => $condrec) { // look for matching condition if (preg_match("!$cond!i", $condString, $mtemp)) { list($dayicon, $nighticon, $condition) = explode("\t", $condrec); if (preg_match('|night|i', $daynight)) { $iconnumb = $nighticon; } else { $iconnumb = $dayicon; } break; } } // end of conditions search return $iconnumb; } // ------------------------------------------------------------------ ?>

Komoka village weather

Latitude N 42° 57' 15"    Longitude W 81° 26' 06"    Elevation 244 m

Nearby METAR Reports

 

$value) { $URL_for_action .= $iCount ? '&' : '?'; $iCount++; $URL_for_action .= $key . '=' . $value; } } ?>
Choose here the aerodromes to show
$value_input) // work through all airfields in the international list { ?>
' .$value_input; ?>'> " . $aerodrome['name'] . ""; ?>
Select either First Fifteen or First Five or As Ticked FIRST FIFTEEN>
FIRST FIVE>
AS TICKED>
$value_input) { if(strlen($key_input) == 8 && $value_input == '15') { $iCount = 0; foreach ($internatIdArray as $key_input => $value_input) // work through all airfields in the international list { if($iCount < 15) $icao_station = $icaoIdArray[] = $key_input; // select first fifteen $iCount++; } break; }elseif(strlen($key_input) == 8 && $value_input == 'five') { $iCount = 0; foreach ($internatIdArray as $key_input => $value_input) // work through all airfields in the international list { if($iCount < 5) $icao_station = $icaoIdArray[] = $key_input; // select first five $iCount++; } break; }elseif(strlen($key_input) == 4) { $icao_station = $icaoIdArray[] = $key_input; } } ?> ""
Now, ' . count($icaoIdArray) . ' airfield(s) selected

'; # print_array($icaoIdArray, 'Selected airfields'); for($i=1; $i <= count($icaoIdArray); $i++) { //----------------------------------------------------------------- // Code fragment to fetch the METAR applicable to this web page //----------------------------------------------------------------- $station = $icaoIdArray[$i - 1]; $stationURL = $rawMETARpath . $station . '.TXT'; # echo '
' . $stationURL; # In fetch function, 2nd parameter set to true means file obtained using file function # In fetch function, 2nd parameter set to false means file obtained using curl function $fetched_METAR = mtr_fetchUrlWithoutHanging($stationURL, false); # echo "Fetched by curl method '" . $fetched_METAR . "'"; if(!strpos($fetched_METAR,$station)) continue; // try next one, if cannot download this METAR $show_diagnostics = $show_diagnosticsR = false; if(isset($_GET['debug']) and $_GET['debug'] == $station) $show_diagnosticsR = true; if(isset($_GET['debug']) and $_GET['debug'] != $station) $show_diagnosticsR = false; if(isset($_GET['debug']) and $_GET['debug'] == 'yes') $show_diagnostics = $show_diagnosticsR = true; if(isset($_GET['debug']) and $_GET['debug'] == 'some') $show_diagnosticsR = true; $decodedOutput = SPAWS_identify_groups ($fetched_METAR, $show_diagnosticsR, $show_diagnostics, $show_diagnostics); // call decoder $j = (3 + $i); switch ($j%3) { case 0: echo "
"; echo "
"; break; case 1: echo "
"; break; case 2: echo "
"; } novel_disp_table($decodedOutput); echo "
"; if($j%3 == 2 or $i == 1 + count($icaoIdArray)) { echo "
"; } } ?>

Glossary - click to open/close
METAR
an acronym of the French "MÉTéorologique Aviation Régulière"
a standard format for "routine weather reports from an aerodrome" defined by the International Civil Aviation Organization (ICAO) and World Meteorological Organisation (WMO).
The Traditional Alphanumeric Characters (TAC) format for a METAR weather report consists of abbreviations, contractions, numbers, plain language, and symbols to provide a uniform means of disseminating surface weather reports
An alternative METAR format (not decoded by this suite) uses XML and GML, these are mark-up languages that are readable by a computer and designed for a geographic based output.
Oktas
equivalent to the numerator for fraction using eighths; dividing the sky into eighths replaces Canada's previous system of dividing the sky into ten parts
a standard format for describing cloud amounts, dating from the old map-based reporting summary system
originally used the digits from 0 to 9, where 0 means no cloud visible, 1 to 8 represent parts with cloud if sky divided into 8 parts, and 9 meant fog or some other weather phenomena obscured view of the sky
Feels Like
There are several formulae to convert air temperature into a feels like temperature, they all use the temperature as an input, almost all then take wind speed (higher wind speed increases cooling effect and reduces feels like value) and most consider humidity (higher humidity increases discomfort and therefore increases feels like value) and combine the three values to create the result.   A few take sunshine into account.   Depending on how the formula is constructed the result may be quoted as an index (not in temperature units) or as an alternative temperature.
Different authorities use different formulae even for calculating a specific variant of feels like temperature such as what is called 'wind chill', so the figures seen here may be not consistent with those quoted by others.   Sometimes, feels like is calculated from wind chill at low temperatures and from heat index at high temperatures, while a yet different formula is used at in-between temperatures.
Most of the named feels like temperatures quoted here are using formulae specific to a particular country and that country is named in the label.
Atmospheric Pressure
The standard for meteorological reports is the pressure corrected to sea level, so that the figure is comparable world-wide. Pilots use the term "Nautical Height" for sea level and hence the internationally recognised code for this in audio communications is "QNH".
Pilots often have an interest in the pressure at cockpit level (approximately 10 feet above runway) because that helps them to set their Altimeter, and traditionally in the North America region this was the pressure reported in the standard pressure Group in each METAR report, with the sea level pressure being reported as additional information in the Remarks Group.
Both Canada and USA now report the pressure at runway level as the altimeter pressure in the standard pressure Group in each METAR report, and pilots use the term "Field Elevation" for airfield/runway level pressure and hence the internationally recognised code for this in audio communications is "QFE".

METAR decoding suite of scripts, and this web page, from SPAWS - © July 2017 - February 2018
Last updates

Set of NOAA style condition icons representing weather and cloud (and some associated script) are taken from Saratoga-Weather.org


Background web page structure updated 24 Feb 2018
powered by Cumulus v1.9.4 (1099)

Written in languages indicated:

PHP logoPHP Hypertext Preprocessor script. HTML5 logoModern Hyper Text Mark-up Language made with cascading style sheetsExternal styling

© This web page script was specially written for Paul and is intellectual property of SPAWS author 24 Feb 2018