Wednesday, October 6, 2010

Weather News App in Processing



//I wrote this code for ArtD-251 Class

//In this project I’m using a java library called Text to Speech in order to
//read the weather RSS Feed and also show the text on the screen. The weather
//information will be for Eugene, OR.
//I used Regex for parsing the html format of the feed and removing all the html
//tags and changing the abbreviations to the actual words (like SW to Southwest).
//I made the anchor animated by using the frameCount function but there was a problem
//with using TTS which pauses the animation while doing the text to speech function!
//**** THIS PROGRAM DOES NOT RUN IN THE BROWSERS AS AN APPLET, FOR AN UNKNOWN REASON!
//SO PLEASE DOWNLOAD THE WHOLE PROJECT’S ZIP FILE AND RUN IT IN PROCESSING.
Code:
import processing.xml.*;
//this is the library that must be imported in order to use the text to speech function
import guru.ttslib.*;

//defining a new text to speech class
TTS tts;

//defining new shapes for background and the person and his moving hand
PShape bg;
PShape p;
PShape hand;

//two inegers for animating and fading in/out by using opacity
int timeline=0,textAlpha=0;
//man's width and heght and rotation PI of the hand
int mw,mh;
float handAng=-1.7;

//defining global variables to request and store feeds for eugene's weather
XMLElement xml;
ArrayList forcastDays;

//----------------------------------SETUP-----------------------------------
void setup(){
  size(960,590);
  smooth();
  frameRate(30);

  //defining a new array to store the next 4 forcast days
  forcastDays = new ArrayList();

  //loading the vector based graphics instead of drawing them
  bg=loadShape("bg.svg");
  hand=loadShape("dast.svg");
  p=loadShape("pman2.svg");

  //setting the person's size
  mw=30;
  mh=10;

  //new text to speech class defining
  tts = new TTS();
  //-------RSS-------

  // Load RSS feed
  try{
    String url = "http://feeds.weatherbug.com/rss.aspx?zipcode=97401&feed=currtxt,fcsttxt&zcode=z4641";
    String imgUrl = "http://feeds.weatherbug.com/rss.aspx?zipcode=97402&feed=curr,fcst&zcode=z4641";
    XMLElement rss = new XMLElement(this, url);
    //Get title of each element
    XMLElement[] titleXMLs = rss.getChildren("channel/item/title");
    XMLElement[] descXMLs = rss.getChildren("channel/item/description");
    XMLElement[] dateXMLs = rss.getChildren("channel/item/pubDate");

    //Get Images

    XMLElement imgRss = new XMLElement(this, imgUrl);
    XMLElement[] imgXMLs = imgRss.getChildren("channel/item/description");


    for (int i = 0; i < titleXMLs.length; i++) {
      //adding new array child including the forcast informations
      forcastDays.add(new forcastDay(titleXMLs[i].getContent(),textCleaner(dateXMLs[i].getContent()),imgExtract(imgXMLs[i].getContent()),textCleaner(descXMLs[i].getContent())));
    }
  }
  catch (Throwable e){
    tts.speak("There is a problem with your internet connnection. we are unable to read the RSS feed from internet at the moment.");
  }
}

//----------------------------------DRAW------------------------------
void draw(){

  background(33);

  //dreaing the first scene
  Scene1();
}

void drawHand(){
  //drawing the hand based on new rotation value
  pushMatrix();



  // moving the hand in order to rotate by the right-button of the hand

  translate(700,208);
  rotate(handAng);
  shape(hand, -144, -140, 144, 173);

  popMatrix();

}


void mousePressed() {
  //taking the person to the begining of the news
  if (frameCount> 120)frameCount=0;

}

//------------------------------------Animation Code---------------------
void anime(){
  //a function to determine when the frame rate would be less than 30 fps
  //println(frameCount + " " + frameRate);

  //
  if (frameCount>10 && frameCount<30){
    handAng-=0.01;
  }
  else if (frameCount>30 && frameCount<230){
    //J is the index of curent forcast day
    int j=timeline;
    forcastDay p = (forcastDay) forcastDays.get(j);
    //println(p.fTitle);

    //loading the weather image
    PImage img = loadImage(p.fImage);
    image(img, 120,50);

    //loading, showing and formatting the text for weather cast info based on the index day
    PFont font;
    font = loadFont("Bellfont.vlw");
    textFont(font);
    String pt = p.fTitle,pd=p.fDescription,pdate=p.fDate;
    fill(0);
    text(pt, 175, 50, 300, 100);
    font = loadFont("Deja11.vlw");
    textFont(font);
    //using the global variable 'textAlpha' to fade in and fade out thae text
    fill(200,33,33,textAlpha*2);
    text(pdate, 120,95,500,500);
    fill(00,00,00,textAlpha*2);
    text(pd, 100,120,500,500);


    if(frameCount==33)tts.speak("Welcome to our website. This is the Current local Weather and Weather Forecast.");
    //println(p.fDate + "  " + textCleaner(p.fDate));
    if (frameCount>35 && frameCount<45){
      handAng-=-0.12;
      if (textAlpha<100)textAlpha+=20;
    }
    if (frameCount==47){
      tts.speak("As of Today, " +pdate);
      tts.speak(p.fTitle);
      tts.speak(p.fDescription);

    }
    //fading in on frame 49 to 61 and moving the arm
    if (frameCount>49 && frameCount<61){
      handAng-=-0.07;
      if (textAlpha>0)textAlpha-=20;
    }
    if (frameCount==62){
      if (timeline<forcastDays.size()-1)timeline++;
    }

    if (frameCount>65 && frameCount<75){
      handAng-=+0.07;
      if (textAlpha<100)textAlpha+=20;
    }
    if (frameCount==78){
      tts.speak(p.fTitle);
      tts.speak(p.fDescription);

    }
    if (frameCount>79 && frameCount<89){
      handAng-=-0.07;
      if (textAlpha>0)textAlpha-=20;
    }
  }
  //doin a loop kind of thing until it read all days
  if (frameCount==92 && timeline<forcastDays.size()-1)frameCount=61;

  //moving the hand
  if (frameCount>92 && frameCount<102)  handAng-=+0.10;
  ;
  //ending the presentaton
  if (frameCount==102) tts.speak("thank you for watching our weather program. Come back again.");
  if (frameCount<103) mouthmove();

}


//a function that finds <img> tags from the feed
String imgExtract(String htmlCode){

  Pattern p=null;
  Matcher m= null;
  String word0= null;
  String word1= null;
  // using regex to find img tax
  p= Pattern.compile(".*<img[^>]*src=\"([^\"]*)",Pattern.CASE_INSENSITIVE);
  m= p.matcher(htmlCode);
  while (m.find())
  {
    //finding the first match
    word0=m.group(1);

  }

  return word0;


}
//this function removes all the html elements from the feed and also replaces the abbreviation
String textCleaner(String txt){
  //clears all html tags
  String noHTMLString = txt.replaceAll("\\<.*?\\>", "");
  //clears all tabspaces
  noHTMLString = noHTMLString.replaceAll("&nbsp;", "");
  //clears quotation marks
  noHTMLString = noHTMLString.replaceAll("&quot;", "");
  //replaces the fahrenheit symbol with text
  noHTMLString = noHTMLString.replaceAll("&deg;F", "degrees Fahrenheit");
  //by using a 2d array we cross-replace the abbreviations
  String names1[]={
    "Northwest by west","Southwest by west","Northeast by east","Northeast by north","Northwest by north","Southwest by south","North by east","North-northeast","East-northeast","East by north","East by south","East-southeast","Southeast by east","Southeast by south","South-southeast","South by east","South by west","South-southwest","West-southwest","West by south","West by north","West-northwest","North-northwest","North by west","Northeast","Northwest","Southeast","Southwest","East","South","West","North","miles per hour","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December","Greenwich Mean Time"              };
  String abrevs1[]={
    "NWbW","SWbW","NEbE","NEbN","NWbN","SWbS","SEbE","SEbS","NbE","NNE","ENE","EbN","EbS","ESE","SSE","SbE","SbW","SSW","WSW","WbS","WbN","WNW","NNW","NbW","NE","NW","SE","SW","E","S","W","N","mph","Mon","Tue","Wed","Thu","Fri","Sat","Sun", "Jan" ,"Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec","GMT"              };

  for(int ii=0;ii<names1.length;ii++){
    noHTMLString = noHTMLString.replaceAll(abrevs1[ii],names1[ii]);

  }
  noHTMLString = noHTMLString.replaceAll("\t", "\n");
  noHTMLString = noHTMLString.replaceAll("\n{3,}", "\n\r\n");
  noHTMLString = trim(noHTMLString);


  // println(noHTMLString);
  return noHTMLString;
}
// a class that contains all the forcast info we get off of feeds
class forcastDay{
  String fTitle,fDate,fImage,fDescription;
  forcastDay (String T,String D, String I, String De) {
    fTitle = T;
    fDate = D;
    fImage = I;
    fDescription = De;
  }
}

//drawing first scene of the animation
void Scene1(){

  shape(bg,0,0,960,590);



  drawHand();
  shape(p, 500, 0, 420, 600);

  ellipse(750,180,mw,mh);


  anime();
}

// a function to move the mouse and make the anchor talking
void mouthmove(){

  if(mw==30){
    mw=20;
    mh=20;
  }
  else if(mw==20){
    mw=30;
    mh=10;
  }

}






No comments:

Post a Comment