Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added location link and unit controls

  • Loading branch information...
commit 4645b2cb9e3487287bffd0ead4bde4d49ba58c92 1 parent 7818de1
david hamp-gonsalves authored
9 src/com/hourlyweather/web/HourlyForecastBuilder.java
@@ -48,9 +48,9 @@ public static void writeForecast(HourlyForecast forecast, Writer writer) {
48 48 jsonHour.put("sunUp", forecastHour.isSunUp());
49 49 jsonHour.put("symbolCode", forecastHour.getSymbolCode());
50 50 jsonHour.put("hour", hourFormatter.print(forecastTime));
51   - jsonHour.put("wind", formatWindSpeed(forecastHour));
52   - jsonHour.put("temp", formatTemperature(forecastHour));
53   - jsonHour.put("precip", formatPrecipitation(forecastHour));
  51 + jsonHour.put("wind", forecastHour.getWindSpeed());
  52 + jsonHour.put("temp", forecastHour.getTemp());
  53 + jsonHour.put("precip", forecastHour.getPrecipitation());
54 54
55 55 jsonForecastHours.put(i, jsonHour);
56 56 } else {
@@ -103,8 +103,7 @@ public static String formatPrecipitation(ForecastHour forecastHour) {
103 103 }
104 104
105 105 public static String formatWindSpeed(ForecastHour forecastHour) {
106   - return windSpeedFormat.format(forecastHour.getWindSpeed() * 3.6)
107   - + " km/h";
  106 + return windSpeedFormat.format(forecastHour.getWindSpeed()); // in miles
108 107 }
109 108
110 109 }
149 war/hourlyWeatherByLocation.jsp
@@ -104,6 +104,20 @@
104 104 min-height: 500px;
105 105 margin-top:-20px;
106 106 }
  107 +
  108 + #controls {
  109 + float:right;
  110 + }
  111 +
  112 + #controls select {
  113 + height:35px;
  114 + margin-right:5px;
  115 + }
  116 +
  117 + #side-bar {
  118 + width:200px;
  119 + float:left;
  120 + }
107 121
108 122 .hour {
109 123 background:rgb(250,250,250);
@@ -347,7 +361,6 @@
347 361 Wherever you are Hour Weather takes the hassle out of checking the forecast by figuring out the nearest weather station automatically. Stop bookmarking local weather forecasts and let Hour Weather simplify your day.
348 362 </div>
349 363 </div>
350   -
351 364
352 365 <div id=about class=content>
353 366 <h3>about</h3>Hour Weather uses the geo capatabilities of HTML5 to determine your rough location and then based on that is able to create a forecast just for you using the awesome <a href='http://www.yr.no/'>yr.no</a> weather service.
@@ -392,6 +405,13 @@
392 405 });
393 406
394 407 window.locationReturned = false;
  408 + if (typeof(localStorage) == 'undefined' )
  409 + alert('Sorry, your browser is just too old to handle this site.');
  410 + else if(isFirstVisit()) {
  411 + localStorage.setItem('celsius', true);
  412 + localStorage.setItem('metric', true);
  413 + }
  414 +
395 415 jQuery.easing.def = "easeOutBounce";
396 416
397 417 if (navigator.geolocation) {
@@ -399,58 +419,139 @@
399 419 //request location
400 420 navigator.geolocation.getCurrentPosition(getForecast, showLocationError, {timeout: 5000});
401 421 } else {
402   - alert('Your browser is just to darn old, and doesn\'t support GeoLocation. Sorry.');
  422 + alert('Sorry but your browser is just to darn old. It doesn\'t support GeoLocation.');
403 423 }
404 424
405 425 function getForecast(position) {
406 426 window.locationReturned = true;
407 427 setPermissionVisibility(false);
  428 +
408 429 //set loading indicator
409   - $('#forecast').html('<div class=loading><div class=obj></div><div class=loading-text>loading...!</div></div>');
410   - $.getJSON("HourlyWeatherByLocation", {lat: position.coords.latitude, long: position.coords.longitude, timezoneOffset: - new Date().getTimezoneOffset()/60}, displayForecast).error(showError);
  430 + $('#main').html('<div class=loading><div class=obj></div><div class=loading-text>loading...!</div></div>');
  431 +
  432 + $.getJSON("HourlyWeatherByLocation", {lat: position.coords.latitude, long: position.coords.longitude, timezoneOffset: - new Date().getTimezoneOffset()/60}, function(json) {displayForecast(json, position);}).error(showError);
  433 + //displayForecast({"forecastHours":[{"wind":1.7,"symbolCode":3,"precip":0,"temp":7.9,"sunUp":true,"hour":"04:00 PM","date":"Tuesday, November 29"},{"wind":1.7,"symbolCode":3,"precip":0,"temp":7.9,"sunUp":false,"hour":"05:00 PM"},{"wind":1.7,"symbolCode":3,"precip":0,"temp":7.9,"sunUp":false,"hour":"06:00 PM"},{"wind":2.6,"symbolCode":3,"precip":0,"temp":6.8,"sunUp":false,"hour":"07:00 PM"},{"wind":2.6,"symbolCode":3,"precip":0,"temp":6.8,"sunUp":false,"hour":"08:00 PM"},{"wind":2.6,"symbolCode":3,"precip":0,"temp":6.8,"sunUp":false,"hour":"09:00 PM"},{"wind":2.3,"symbolCode":4,"precip":0.016666666666666666,"temp":7.3,"sunUp":false,"hour":"10:00 PM"},{"wind":2.3,"symbolCode":4,"precip":0.016666666666666666,"temp":7.3,"sunUp":false,"hour":"11:00 PM"},{"wind":2.3,"symbolCode":4,"precip":0.016666666666666666,"temp":7.3,"sunUp":false,"hour":"12:00 AM","date":"Wednesday, November 30"},{"wind":2.1,"symbolCode":9,"precip":0.06666666666666667,"temp":8.8,"sunUp":false,"hour":"01:00 AM"},{"wind":2.1,"symbolCode":9,"precip":0.06666666666666667,"temp":8.8,"sunUp":false,"hour":"02:00 AM"},{"wind":2.1,"symbolCode":9,"precip":0.06666666666666667,"temp":8.8,"sunUp":false,"hour":"03:00 AM"},{"wind":3.5,"symbolCode":3,"precip":0.049999999999999996,"temp":11.1,"sunUp":false,"hour":"04:00 AM"},{"wind":3.5,"symbolCode":3,"precip":0.049999999999999996,"temp":11.1,"sunUp":false,"hour":"05:00 AM"},{"wind":3.5,"symbolCode":3,"precip":0.049999999999999996,"temp":11.1,"sunUp":false,"hour":"06:00 AM"},{"wind":5.8,"symbolCode":9,"precip":0.25,"temp":12.4,"sunUp":true,"hour":"07:00 AM"},{"wind":5.8,"symbolCode":9,"precip":0.25,"temp":12.4,"sunUp":true,"hour":"08:00 AM"},{"wind":5.8,"symbolCode":9,"precip":0.25,"temp":12.4,"sunUp":true,"hour":"09:00 AM"},{"wind":7.3,"symbolCode":10,"precip":1.5,"temp":13.8,"sunUp":true,"hour":"10:00 AM"},{"wind":7.3,"symbolCode":10,"precip":1.5,"temp":13.8,"sunUp":true,"hour":"11:00 AM"},{"wind":7.3,"symbolCode":10,"precip":1.5,"temp":13.8,"sunUp":true,"hour":"12:00 PM"},{"wind":8.6,"symbolCode":10,"precip":2.6833333333333336,"temp":13.6,"sunUp":true,"hour":"01:00 PM"},{"wind":8.6,"symbolCode":10,"precip":2.6833333333333336,"temp":13.6,"sunUp":true,"hour":"02:00 PM"},{"wind":8.6,"symbolCode":10,"precip":2.6833333333333336,"temp":13.6,"sunUp":true,"hour":"03:00 PM"},{"wind":8.3,"symbolCode":10,"precip":2.1999999999999997,"temp":13.6,"sunUp":true,"hour":"04:00 PM"},{"wind":8.3,"symbolCode":10,"precip":2.1999999999999997,"temp":13.6,"sunUp":false,"hour":"05:00 PM"},{"wind":8.3,"symbolCode":10,"precip":2.1999999999999997,"temp":13.6,"sunUp":false,"hour":"06:00 PM"},{"wind":7.6,"symbolCode":9,"precip":0.7833333333333333,"temp":13.4,"sunUp":false,"hour":"07:00 PM"},{"wind":7.6,"symbolCode":9,"precip":0.7833333333333333,"temp":13.4,"sunUp":false,"hour":"08:00 PM"},{"wind":7.6,"symbolCode":9,"precip":0.7833333333333333,"temp":13.4,"sunUp":false,"hour":"09:00 PM"},{"wind":4.4,"symbolCode":3,"precip":0,"temp":11.2,"sunUp":false,"hour":"10:00 PM"},{"wind":4.4,"symbolCode":3,"precip":0,"temp":11.2,"sunUp":false,"hour":"11:00 PM"},{"wind":4.4,"symbolCode":3,"precip":0,"temp":11.2,"sunUp":false,"hour":"12:00 AM","date":"Thursday, December 01"},{"wind":2,"symbolCode":3,"precip":0,"temp":8.6,"sunUp":false,"hour":"01:00 AM"},{"wind":2,"symbolCode":3,"precip":0,"temp":8.6,"sunUp":false,"hour":"02:00 AM"},{"wind":2,"symbolCode":3,"precip":0,"temp":8.6,"sunUp":false,"hour":"03:00 AM"}]}, position);
411 434 }
412 435
413   - function displayForecast(json) {
  436 + function displayForecast(json, position) {
  437 + window.forecastData = json;
  438 +
414 439 //make sure the dom is ready
415 440 $().ready(function() {
416   - if(json.error != undefined)
417   - alert(json.error);
  441 + if(window.forecastData.error != undefined)
  442 + alert(window.forecastData.error);
418 443
419   - var forecastHours = json.forecastHours;
  444 + var forecastHours = window.forecastData.forecastHours;
420 445
421 446 //set the day/night status + set the position
422 447 animateDiorama(forecastHours[0]);
423 448
424   - var forecastLength = forecastHours.length;
425 449 var forecastArea = $('#forecast');
426   - forecastArea.empty();
  450 + forecastArea.html('');
  451 + var forecastLength = forecastHours.length;
427 452 for(var i=0; i < forecastLength ; i += 1) {
428 453 var hour = forecastHours[i];
429 454 if(hour.date != undefined)
430   - forecastArea.append('<div class=day-start>' + hour.date + '</div>');
  455 + if(i == 0)
  456 + forecastArea.append('<div class=day-start>' + hour.date + ' @ <a href=\'http://maps.google.com/maps?q=' + position.coords.latitude + ',' + position.coords.longitude + '\'>(' + Math.round(position.coords.latitude) + '&deg;,' + Math.round(position.coords.longitude) + '&deg;)</a><div id=controls><label>units: </label><select id=units><option value=metric>metric</option><option value=imperial>imperial</option></select> <select id=temp-units><option value=celsius>celsius</option><option value=fahrenheit>fahrenheit</option></select></div></div>');
  457 + else
  458 + forecastArea.append('<div class=day-start>' + hour.date + '</div>');
431 459 //add the forecast data to the forecast area
432   - forecastArea.append('<div class=\'hour ' + (hour.sunUp ? '':'night ') + (i % 2 == 0 ? '':'alt') + '\'> <div class=time>' + hour.hour + '</div> <div class=\'symbol obj\' style=\'background-position:' + (-71.5 * (hour.symbolCode - 1)) + (hour.sunUp ? 'px -160px':'px -230px') + '\'></div> <div class=\'temp ' + (isCold(hour) ? 'cold':'') + (isHot(hour) ? 'hot':'') + '\'><label>temperature: </label>' + hour.temp + '</div> <div class=\'wind ' + (isWindy(hour)? 'windy':'') + '\'><label>wind speed: </label>' + hour.wind + '</div> <div class=precip><label>precipitation: </label>' + hour.precip + '</div> </div>');
  460 + forecastArea.append('<div class=\'hour ' + (hour.sunUp ? '':'night ') + (i % 2 == 0 ? '':'alt') + '\'> <div class=time>' + hour.hour + '</div> <div class=\'symbol obj\' style=\'background-position:' + (-71.5 * (hour.symbolCode - 1)) + (hour.sunUp ? 'px -160px':'px -230px') + '\'></div> <div class=\'temp ' + howHot(hour) + '\'><label>temperature: </label><span class=val>' + getTemp(hour) + '</span></div> <div class=\'wind ' + howWindy(hour) + '\'><label>wind speed: </label><span class=val>' + getWind(hour) + '</span></div> <div class=precip><label>precipitation: </label><span class=val>' + getPrecip(hour) + '</span></div> </div>');
433 461 }
434 462
  463 + //hook up the control events/settings
  464 + var controls = $('#controls');
  465 + controls.find('select').change(updateUnitConfig);
  466 + controls.find('#temp-units').val(isCelsius() ? 'celsius':'fahrenheit');
  467 + controls.find('#units').val(isMetric() ? 'metric':'imperial');
435 468 });
436 469 }
437 470
438   - function isCold(hour) {
439   - if(hour.temp[0] === '-')
440   - return true;
441   - return false;
  471 + function howHot(hour) {
  472 + if(hour.temp > 24)
  473 + return 'hot';
  474 + if(hour.temp > 14)
  475 + return 'warm';
  476 + if(hour.temp < 1)
  477 + return 'cold';
442 478 }
443 479
444   - function isHot(hour) {
445   - if(hour.temp[0] > 1 && parseInt(hour.temp[1]) >= 0 && parseInt(hour.temp[1]) <= 9)
446   - return true;
447   - return false;
  480 + function howWindy(hour) {
  481 + if(hour.wind > 25)
  482 + return 'strong';
  483 + if(hour.wind > 10)
  484 + return 'moderate';
  485 + return 'light';
448 486 }
449 487
450   - function isWindy(hour) {
451   - if(hour.wind[0] > 2 && parseInt(hour.wind[1]) >= 0 && parseInt(hour.wind[1]) <= 9)
452   - return true;
453   - return false;
  488 + function getTemp(hour) {
  489 + if(isCelsius())
  490 + return Math.round(hour.temp) + '\u2103';
  491 + else
  492 + return Math.round(1.8 * hour.temp + 32) + '\u2109';
  493 + }
  494 +
  495 + function getWind(hour) {
  496 + if(isMetric())
  497 + return Math.round(hour.wind * 3.6) + ' km/h';
  498 + else
  499 + return Math.round(hour.wind) + ' mph';
  500 + }
  501 +
  502 + function getPrecip(hour) {
  503 + if(hour.precip == 0) return 'none';
  504 +
  505 + var precip;
  506 + if(isMetric()) precip = formatDouble(hour.precip);
  507 + else precip = formatDouble(hour.precip * 0.03937);
  508 +
  509 + if(precip === 0) return 'trace';
  510 +
  511 + if(isMetric()) return precip + ' mm';
  512 + else return precip + '\'';
  513 + }
  514 +
  515 + function formatDouble(double) {
  516 + return Math.round(double * 100) / 100;
  517 + }
  518 +
  519 + function isMetric() {return localStorage.getItem('metric') === 'true';}
  520 + function isCelsius() {return localStorage.getItem('celsius') === 'true';}
  521 + function isFirstVisit() {return localStorage.getItem('metric') == null;}
  522 +
  523 + function updateUnitConfig() {
  524 + var setting = $(this).val();
  525 + switch(setting)
  526 + {
  527 + case 'metric':
  528 + localStorage.setItem('metric', true);
  529 + break;
  530 + case 'imperial':
  531 + localStorage.setItem('metric', false);
  532 + break;
  533 + case 'celsius':
  534 + localStorage.setItem('celsius', true);
  535 + break;
  536 + case 'fahrenheit':
  537 + localStorage.setItem('celsius', false);
  538 + break;
  539 + }
  540 +
  541 + updateForecast();
  542 + }
  543 +
  544 + function updateForecast() {
  545 + var hourNodes = $('#forecast').children('.hour');
  546 +
  547 + var forecastHours = window.forecastData.forecastHours;
  548 + var forecastLength = forecastHours.length;
  549 + for(var i=0; i < forecastLength ; i += 1) {
  550 + var hour = forecastHours[i];
  551 + $(hourNodes[i]).find('.temp .val').html(getTemp(hour));
  552 + $(hourNodes[i]).find('.wind .val').html(getWind(hour));
  553 + $(hourNodes[i]).find('.precip .val').html(getPrecip(hour));
  554 + }
454 555 }
455 556
456 557 function animateToDark(object) {

0 comments on commit 4645b2c

Please sign in to comment.
Something went wrong with that request. Please try again.