1/* ************************************* 2 * Weather Site JavaScript Functions 3 ************************************* */ 4// Making sure the JS file is working // 5console.log('My JS is being Read.'); 6 7// console.log('Header and Storage starting from functions.js'); 8 9// Set global variable for custom header required by NWS API 10var idHeader = { 11 headers: { 12 "User-Agent": "Student Learning Project - [email protected]" 13 } 14}; 15 16// Setup localStorage 17var storage = window.localStorage; 18 19 20// buildWC will just build the wind chill factor and change the innerHTML 21// console.log will help debug if needed 22function buildWC(speed, temp) { 23 console.log("Speed: " + speed + " Temp: " + temp); 24 // get the id of the element 25 const feelTemp = document.getElementById('feels'); 26 // do fancy maths 27 let wc = 35.74 + 0.6215 * temp - 35.75 * Math.pow(speed, 0.16) + 0.4275 * temp * Math.pow(speed, 0.16); 28 // console.log(wc); 29 console.log("Wind Chill 1: " + wc); 30 wc = Math.floor(wc); 31 // determine the smallest temperature for the tinal result 32 wc = (wc > temp) ? temp : wc; 33 console.log("WIND CHILL: " + wc); 34 // change the HTML of 'feels' (const created earlier as feelTemp) 35 if (wc != null) { 36 feelTemp.innerHTML = wc; 37 } 38} 39 40// getCondition() will test a series of statements and determine what 41// the weather condition should be defined as so we can change the picture 42// console.log will debug throughout 43function getCondition(statement) { 44 // Make them all lower case // 45 statement = statement.toLowerCase(); 46 // console.log("statement passed to getCondition() is: " + statement); 47 // create an empty condition (I still don't get why let is preferred over var) 48 let condition = ""; 49 50 // Start the if statement. Not necessarily neat, but still preferred over 51 // switch statements 52 if (statement == 'cloudy' || 53 statement == 'overcast' || 54 statement == 'mostly cloudy' || 55 statement == 'gloomy') { 56 // Condition change 57 condition = 'clouds'; 58 // console.log("Condition is: " + condition); 59 return condition; 60 } else if (statement == 'snow' || 61 statement == 'snowy' || 62 statement == 'snowing' || 63 statement == 'flurries') { 64 // Condition change 65 condition = 'snow'; 66 // console.log("Condition is: " + condition); 67 return condition; 68 } else if (statement == 'foggy' || 69 statement == 'low visibility' || 70 statement == 'smoggy' || 71 statement == 'haze' || 72 statement == 'hazey') { 73 // Condition change 74 condition = 'fog'; 75 // console.log("Condition is: " + condition); 76 return condition; 77 } else if (statement == 'pouring' || 78 statement == 'raining' || 79 statement == 'raining cats and dogs' || 80 statement == 'dumping buckets' || 81 statement == 'rain' || 82 statement == 'precipitation' || 83 statement == 'high precipitation' || 84 statement == 'wet weather') { 85 // Condition change 86 condition = 'rain'; 87 // console.log("Condition is: " + condition); 88 return condition; 89 } else { 90 condition = 'clear'; 91 // console.log("Condition is: " + condition); 92 return condition; 93 } 94} 95 96// changeSummaryImage() will simply change the element 'content' to have the 97// class of whatever weather factor we can determine using the getCondition() 98// function. 99function changeSummaryImage(condition) { 100 document.getElementById('content').setAttribute("class", condition); 101 document.getElementById('weather-picture').setAttribute("src", "images/" + condition + "-small.jpg"); 102 document.getElementById('weather-picture').setAttribute("alt", condition + " weather condition image"); 103 return 0; 104} 105 106// convertMeters() will take meters and turn them to feet and return an integer. 107function convertMeters(meters) { 108 let feet = meters * 3.28084; 109 feet = Math.round(feet); 110 return feet; 111} 112 113// setElevation is going to change the elevation to feet from meters 114function setElevation(feet) { 115 document.getElementById('elevation').innerHTML = feet; 116} 117 118// Convert, Format time to 12 hour format 119function format_time(hour) { 120 if (hour > 23) { 121 hour -= 24; 122 } 123 let amPM = (hour > 11) ? "pm" : "am"; 124 if (hour > 12) { 125 hour -= 12; 126 } 127 if (hour == 0) { 128 hour = "12"; 129 } 130 return hour + amPM; 131} 132 133// Build the hourly temperature list 134function buildHourlyData(nextHour, hourlyTemps) { 135 // Data comes from a JavaScript object of hourly temp name - value pairs 136 // Next hour should have a value between 0-23 137 // The hourlyTemps variable holds an array of temperatures 138 // Line 8 builds a list item showing the time for the next hour 139 // and then the first element (value in index 0) from the hourly temps array 140 let hourlyListItems = '<li>' + format_time(nextHour) + ': ' + hourlyTemps[0] + '°F</li>'; 141 // Build the remaining list items using a for loop 142 for (let i = 1, x = hourlyTemps.length; i < x; i++) { 143 hourlyListItems += '<li>' + format_time(nextHour + i) + ': ' + hourlyTemps[i] + '°F</li>'; 144 } 145 // console.log('HourlyList is: ' + hourlyListItems); 146 return hourlyListItems; 147} 148 149/* ---------------------------------------------------------------- Locations Functions Below!! ------------------------------------------------------------ */ 150 151let statusContainer = document.getElementById('status'); 152let contentContainer = document.getElementById('main-content'); 153 154 155// Gets location information from the NWS API 156function getLocation(locale) { 157 const URL = "https://api.weather.gov/points/" + locale; 158 // NWS User-Agent header (built above) will be the second parameter 159 fetch(URL, idHeader) 160 .then(function (response) { 161 if (response.ok) { 162 return response.json(); 163 }
164 throw new ERROR('Response not OK.'); 165 }) 166 .then(function (data) { 167 // Let's see what we got back 168 console.log('getLocation object:'); 169 console.log(data); 170 // Store data to localstorage 171 storage.setItem("locName", data.properties.relativeLocation.properties.city); 172 storage.setItem("locState", data.properties.relativeLocation.properties.state); 173 174 // This is my API Key for the zipCodeAPI if I have time to do it: Yn3ypsoRugytpYooDNI7fUIXnsZB1ciuxPmmmssPnxLRFRFIIlQqBVE9erEaQ6Y1 175 176 let fullName = storage.getItem('locName') + ', ' + storage.getItem('locState'); 177 storage.setItem("locFullName", fullName); 178 179 // Next, get the weather station ID before requesting current conditions 180 // URL for station list is in the data object 181 let stationsURL = data.properties.observationStations; 182 // Call the function to get the list of weather stations 183 getStationId(stationsURL); 184 185 let hourlyURL = data.properties.forecastHourly; 186 getHourly(hourlyURL); 187 let forecastURL = data.properties.forecast; 188 getForecast(forecastURL); 189 190 // Call the buildPage function 191 setTimeout(buildPage(), 5000); 192 193 // storage.setItem("reloadThing", 'Page has not been reloaded yet'); 194 195 // while(storage.getItem('reloadThing') != 'Reloaded Page') 196 // { 197 // storage.setItem('reloadThing', 'Reloaded Page'); 198 // setTimeout(location.reload(), 600); 199 // console.log("---------------------- RELOAD ------------------"); 200 // } 201 202 }) 203 .catch(error => console.log('There was a getLocation error: ', error)) 204} // end getLocation function 205 206// the getStationId() function gets weather station list and the nearest weather station ID from the NWS API 207function getStationId(stationsURL) { 208 // NWS User-Agent header (built above) will be the second parameter 209 fetch(stationsURL, idHeader) 210 .then(function (response) { 211 if (response.ok) { 212 return response.json(); 213 } 214 throw new ERROR('Response not OK.'); 215 }) 216 .then(function (data) { 217 // Let's see what we got back 218 console.log('getStationId object:'); 219 console.log(data); 220 221 // Store station ID and elevation (in meters - will need to be converted to feet) 222 let stationId = data.features[0].properties.stationIdentifier; 223 let stationElevation = data.features[0].properties.elevation.value; 224 console.log('Station and Elevation are: ' + stationId, stationElevation); 225 226 // Store data to localstorage 227 storage.setItem("stationId", stationId); 228 storage.setItem("stationElevation", stationElevation); 229 230 // Request the Current Weather for this station 231 getWeather(stationId); 232 }) 233 .catch(error => console.log('There was a getStationId error: ', error)) 234} // end getStationId function 235 236// Gets current weather information for a specific weather station from the NWS API 237function getWeather(stationId) { 238 // This is the URL for current observation data 239 const URL = 'https://api.weather.gov/stations/' + stationId + '/observations/latest'; 240 // NWS User-Agent header (built above) will be the second parameter 241 fetch(URL, idHeader) 242 .then(function (response) { 243 if (response.ok) { 244 return response.json(); 245 } 246 throw new ERROR('Response not OK.'); 247 }) 248 .then(function (data) { 249 // Are we done yet? No 250 let finished = false; 251 252 // Let's see what we got back 253 console.log('getWeather object:'); 254 console.log(data); 255 256 let todd = data.properties.temperature.value; 257 storage.setItem("test", todd); 258 259 260 // ************ Get the content ****************************** 261 262 // storage - text description 263 storage.setItem('textDescription', data.properties.textDescription); 264 265 }) 266 .catch(error => console.log('There was a getWeather error: ', error)) 267} // end getWeather function 268 269 270// Gets location information from the NWS API 271function getHourly(hourlyURL) { 272 // NWS User-Agent header (built above) will be the second parameter 273 fetch(hourlyURL, idHeader) 274 .then(function (response) { 275 if (response.ok) { 276 return response.json(); 277 }
278 throw new ERROR('Response not OK.'); 279 }) 280 .then(function (data) { 281 // Let's see what we got back 282 console.log('getHourly object:'); 283 console.log(data); 284 // Get the hourly location 285 286 let hourly = []; 287 for (let i = 0; i < 13; i++) { 288 hourly[i] = data.properties.periods[i].temperature; 289 } 290 291 // wind direction, wind speed, current temperature, hourly - set to storage 292 293 storage.setItem('windDirection', data.properties.periods[0].windDirection); 294 storage.setItem('windSpeed', parseFloat(data.properties.periods[0].windSpeed)); 295 storage.setItem('tempCurrent', data.properties.periods[0].temperature); 296 storage.setItem('tempHourly', hourly); 297 298 299 }) 300 .catch(error => console.log('There was a getHourly error: ', error)) 301} // end getHourly function 302 303// Gets location information from the NWS API 304function getForecast(URL) { 305 // NWS User-Agent header (built above) will be the second parameter 306 fetch(URL, idHeader) 307 .then(function (response) { 308 if (response.ok) { 309 return response.json(); 310 } 311 throw new ERROR('Response not OK.'); 312 }) 313 .then(function (data) { 314 // Let's see what we got back 315 console.log('getForecast object:'); 316 console.log(data); 317 318 // high, low, icon, detailedForecast 319 storage.setItem('tempHigh', data.properties.periods[0].temperature); 320 storage.setItem('tempLow', data.properties.periods[1].temperature); 321 322 }) 323 .catch(error => console.log('There was a getForecast error: ', error)) 324} // end getForecast function 325 326 327function buildPage() { 328 329 // ************ Display the content ****************************** 330 331 // // Set the page title to your current location's city and state 332 let pageTitle = document.getElementById('page-title'); 333 let fullName = storage.getItem('locFullName'); 334 335 // // Create a text node containing the full name 336 let fullNameNode = document.createTextNode(fullName); 337 // // inserts the fullName value before any other content that might exist 338 pageTitle.insertBefore(fullNameNode, pageTitle.childNodes[0]); 339 340 341 // Set the Location information 342 // Get the h1 to display the city location 343 // The h1 in main h1 should now say "Greenville, SC" 344 document.getElementById('nameofcity').innerHTML = storage.getItem('locFullName'); 345 346 // Feet to meters, to display 347 let feet = convertMeters(storage.getItem('stationElevation')); 348 setElevation(feet); 349 console.log("buildPage - Elevation in feet: " + feet); 350 351 // Lat and Lon (calculate sign and display properly) 352 let latitude = storage.getItem('geoLat'); 353 let longitude = storage.getItem('geoLon'); 354 signLat = getSign(true, latitude); 355 signLon = getSign(false, longitude); 356 if (latitude < 0) { 357 latitude *= -1; 358 } 359 if (longitude < 0) { 360 longitude *= -1; 361 } 362 document.getElementById('cord').innerHTML = Math.floor(latitude * 100) / 100 + "° " + signLat + " " + Math.floor(longitude * 100) / 100 + "° " + signLon; 363 364 // Set the temperature information 365 document.getElementById('high-temp').innerHTML = storage.getItem('tempHigh') + "°F"; 366 document.getElementById('low-temp').innerHTML = storage.getItem('tempLow') + "°F"; 367 document.getElementById('realtemp').innerHTML = storage.getItem('tempCurrent'); 368 buildWC(storage.getItem('windSpeed'), storage.getItem('tempCurrent')); 369 console.log("buildPage - Windspeed and Temperature set (also called the buildWindChill() function)"); 370 371 // Set the wind information 372 document.getElementById('mph').innerHTML = storage.getItem('windSpeed') + " mph"; 373 document.getElementById('direction').innerHTML = "<strong>Direction: </strong>" + storage.getItem('windDirection') + "</p>"; 374 document.getElementById('gusts').innerHTML = 375 "<strong>Gusts: </strong>" + (parseFloat(storage.getItem("windGusts")) > storage.getItem('windSpeed') ? parseFloat(storage.getItem("windGusts")) : storage.getItem('windSpeed')) + " mph</p>"; 376 console.log("WIND DIRECTION FROM functions[369] " + storage.getItem("windDirection")); 377 windDial(storage.getItem('windDirection')); 378 console.log("Wind Direction: " + storage.getItem('windDirection')); 379 380 // Set the current conditions information 381 const sendCondition = getCondition(storage.getItem('textDescription')); 382 changeSummaryImage(sendCondition); 383 console.log("Weather Condition :" + sendCondition); 384 document.getElementById('loll').innerHTML = storage.getItem('textDescription'); 385 386 // Set the hourly temperature information // 387 // Setting the nextHour to currentHour + 1 388 let date = new Date(); 389 let nextHour = date.getHours() + 1; 390 391 document.getElementById('hourly-info').innerHTML = buildHourlyData(nextHour, storage.getItem('tempHourly').split(',')); 392 393 // Clear everything and make it so that it all appears on the screen 394 document.getElementById('main-content').setAttribute('class', ''); 395 document.getElementById('status').setAttribute('class', 'hide'); 396 console.log("This should be the last thing I see"); 397} 398 399/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/ 400 401 402// changeSummaryImage() will simply change the element 'content' to have the 403// class of whatever weather factor we can determine using the getCondition() 404// function. 405function changeSummaryImage(condition) { 406 document.getElementById('content').setAttribute("class", condition); 407 document.getElementById('weather-picture').setAttribute("src", "images/" + condition + "-small.
407jpg"); 408 document.getElementById('weather-picture').setAttribute("alt", condition + " weather condition image"); 409 return 0; 410} 411 412// convertMeters() will take meters and turn them to feet and return an integer. 413function convertMeters(meters) { 414 let feet = meters * 3.28084; 415 feet = Math.round(feet); 416 return feet; 417} 418 419// setElevation is going to change the elevation to feet from meters 420function setElevation(feet) { 421 document.getElementById('elevation').innerHTML = feet; 422} 423 424// Convert, Format time to 12 hour format 425function format_time(hour) { 426 if (hour > 23) { 427 hour -= 24; 428 } 429 let amPM = (hour > 11) ? "pm" : "am"; 430 if (hour > 12) { 431 hour -= 12; 432 } 433 if (hour == 0) { 434 hour = "12"; 435 } 436 return hour + amPM; 437} 438 439function getSign(isLat, num) { 440 if (num > 0) { 441 if (isLat == true) { 442 return 'N'; 443 } else { 444 return 'E'; 445 } 446 } else { 447 if (isLat == true) { 448 return 'S'; 449 } else { 450 return 'W'; 451 } 452 } 453} 454 455 456 457 458// windDial is what will set the addribute of the dial class // 459function windDial(direction) { 460 // get the dial class 461 const dial = document.getElementById("dial"); 462 // make sure the string is in all upper case characters 463 direction = direction.toUpperCase(); 464 465 // Start the switch (gross)... console.log will help debug if needed 466 switch (direction) { 467 case "North": 468 case "N": 469 dial.setAttribute("class", "n"); 470 // console.log('Wind Pointer Set to North.'); 471 break; 472 case "NE": 473 case "NNE": 474 case "ENE": 475 dial.setAttribute("class", "ne"); 476 // console.log('Wind Pointer Set to North East.'); 477 break; 478 case "NW": 479 case "NNW": 480 case "WNW": 481 dial.setAttribute("class", "nw"); 482 // console.log('Wind Pointer Set to North West.'); 483 break; 484 case "South": 485 case "S": 486 dial.setAttribute("class", "s"); 487 // console.log('Wind Pointer Set to South.'); 488 break; 489 case "SE": 490 case "SSE": 491 case "ESE": 492 dial.setAttribute("class", "se"); 493 // console.log('Wind Pointer Set to South East.'); 494 break; 495 case "SW": 496 case "SSW": 497 case "WSW": 498 dial.setAttribute("class", "sw"); 499 // console.log('Wind Pointer Set to South West'); 500 break; 501 case "East": 502 case "E": 503 dial.setAttribute('class', "e"); 504 // console.log('Wind Pointer Set to East.'); 505 break; 506 case "West": 507 case "W": 508 // console.log("made it") 509 dial.setAttribute("class", "w"); 510 // console.log('Wind Pointer Set to West.'); 511 break; 512 default: 513 // console.log("Nothing Worked... direction: " + direction); 514 } 515} 516 517function celsiusToFahrenheit(degrees) { 518 degrees = parseFloat(degrees); 519 return (valNum - 32) / 1.8; 520}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.