H5 H4 H3 H2 H1 TS/SS TD/SD ET
Choose a storm season: Choose a basin: Speed:

For the final project I created an animated mashup showing hurricane storm tracks using data downloaded from NOAA's International Best Track Archive for Climate Stewardship - World Meteorological Organization database (http://www.ncdc.noaa.gov/oa/ibtracs/index.php?name=wmo-data). This project proved challenging in part because the Google Maps Javascript API doesn't provide any built-in methods to handle animation aside from dropping or bouncing a marker. Animation basically requires preparing images and then displaying them in rapid succession to create the illusion of motion. For data that represents real world events this means starting at a specified time, drawing the relevant features for that time, waiting for a brief interval, then incrementing the time and repeating until you reach the end time. The dataset I chose records storm positions at 6 hour intervals which served as a convenient time step. To further simplify the problem I didn't attempt to make the animation perfectly smooth by interpolating between points. When played while zoomed out to level 3 the jerkiness is almost negligible. My basic strategy was to load the storm data into memory, create all the polylines behind the scenes, then step through time and show the relevant polylines. Managing all the storm data in memory was another challenging aspect of this project. The data needed to be managed in a way that would allow replaying the animation without needing to requery the data from the database. I created an object called stormtrack to help keep track of each storm and all the associated data. The object constructor looks just like any other javascript function, except we'll call it using the new operator and we use the self-referencing "this" keyword to assign properties to the object. The most important properties are the points and tracks arrays used to store the storm track data.

  function stormtrack(name, datestart, dateend, map) {
    this.name = name;
    this.datestart = datestart;
    this.dateend = dateend;
    this.points = [];
    this.tracks = [];
    this.map = map;
    this.marker = new google.maps.Marker();
    this.trackcursor = 0;
  }
  

Constructor functions all have a property called prototype which can be used to attach methods (or additional properties) to objects created with the constructor. I used prototype to add some methods to load the point data and build the track polylines. For example, the addPoint method adds a vertex into the points array using an object literal. This allowed me to attach additional properties to each vertex (date, windspeed, etc.) that could be used later for info windows and symbology.

  stormtrack.prototype.addPoint = function(date, windspeed, nature, lat, lng) {
    this.points.push({date: date,
                      windspeed: windspeed,
                      nature: nature,
                      category: findCategory(windspeed, nature),
                      latlng: new google.maps.LatLng(lat, lng)
                      });
    this.dateend = date;
  }
  

When starting the animation it's simply a matter of looping through each storm, then looping through each track to turn on polylines that exist at a particular date. It wouldn't be very efficient to run through every polyline for every storm for every time step so I included a counter in the stormtrack object (trackcursor) to keep track of the last array index used. This acts like a bookmark during the animation to jump straight to the next polyline to turn on.

Source code for StormTracks.php
Source code for get_storm_data.php