Sandbox For Mapping, Viewing and Analyzing Atlantic Hurricane Data

Sandbox For Mapping, Viewing and Analyzing Atlantic Hurricane Data


Database Search:

By selecting one or more items, from one or more lists, you can constrain which storms are returned by the search and mapped. For example, by only selecting '2005' from Year, the search will return all storms for that year, plot them on the map, and build a (closed) table for each storm. If you also select eg. 'KATRINA' and "RITA" from Name, only those two storms will be returned. Other constraints can be made by using the pull-down menus. More than one such constraint may be added by selecting AND or OR from the 'More..?' menu. The default search behavior is to return ALL points for a storm if ANY of its points match your criteria. But if you check the 'Selected Track Points Only' box, ONLY matching points will be returned.

Database structure was fully changed, it's more simple and queries are a bit faster. It's also based in the original HURDAT file, not the "Easy to Read" version, because the former has some info that the latter doesn't, and also because it's the official source. East Pacific data was also added. More filters have been aggregated.

On the downside, I removed the DB abstraction layer provided with the original version, because I had some problems compiling some of the necessary libraries and I didn't want to expend much time on looking at that :-(. It's in the TODO list to restore it.


Map Navigation:

To PAN the map, use the arrow controls in the top left corner, or hold the left mouse-button while moving the mouse. To ZOOM, use the '+/-' controls below the pan controls. You can also ZOOM IN by double-clicking on the point you want centered in the map. To disable/enable the track and point layers, use the layer control in the top right corner. Mousing-over a track will cause a popup to appear with the storm name, year, and storm number (see Notes below). Clicking on a storm track will cause it to change color, and that track's data table will be opened below the map.


Tabular Data:

To open/close the data table for a given storm, click its '+' or '-' button to the left of the storm name.


Notes and Caveats:

I've done very little yet regarding cross-broswer support. This site is built/tested with FireFox 3. I've noticed that some other browsers (eg. Safari) drop the 'StormType' select-box below the others. Turning off the 'minimum font-size' setting in your browser and reducing font-size helps in some cases. On FireFox, you must turn off the point layer to get popups to show on the track layer.


Depending on search criteria, it can take a while to return and map the data. Be patient. If you use FireFox, you may get a message saying 'Unresponsive script.' If so, follow these short instructions at the FoxMarks Wiki.

There is a known problem with OpenLayers popups, where the popup will not be removed when the mouse leaves the feature (eg. track).

I did some cross-browser testing. IE 7 wasn't working (shocker). It's working now, but it's the slowest (by far) to process the javascript, I suggest that the filtering outputs no more than 30 tracks for IE, otherwise your browser and resources would be hurt badly. Other browsers tested were Safari, Firefox 3 and Chrome. Safari was the fastest, followed by Firefox and then Chrome (all over Windows XP), but on Firefox (as well as IE) you must turn off the point layer to get popups to show on the track layer and to select the track.


"; // this div is closed in build_query.js print "
"; print "

Relevant Links:


"; print "

HURDAT Re-Analysis Project Data
The 'Easy to Read Version' was used for parsing and loading into this site's database.

"; print "

NASA Hurricane Color Legend
The color legend in this site's map was clipped from the NASA image.

"; print "

MySQL 5.0.67 Database System
Free and open source; used to create and search the storm database.

"; print "

PHP 5.2.6
Free and open source; used to create 'static' selectors and to interact with the database.

"; print "

OpenLayers 2.7 Javascript GIS library
Free and open source; used to create and display the Google map and the storm track and datapoint layers.

"; print "

Apache 2.2.9 Web Server
Free and open source; used as the site webserver.

"; print "

Apache Tomcat 6.0.18 Web Service Container
Free and open source. Web application container.

"; print "

Apache Axis2/Java Web Service Engine
Free and open source. Stay tuned! Will be used with Tomcat to access R-Language data analysis features.

"; print "

R   2.8.1
Free and open source. Stay tuned! Will be used to access R-Language data analysis features.

"; print "
"; print "
"; print "

Site Source Code:


"; print "

create-tables.sql
MySQL script used to create the hurricane database.

"; print "

Text2SQL.java
Java program used to parse the HURDAT file and populate the hurricane database.

"; print "

storm_search.php
PHP code for this initial search page.

"; print "

build_query.js
Javascript code that creates the 'dynamic' form items in response to user actions.

"; print "

handle_query.php
PHP code that creates/sends the MySQL query and returns storm data tables.

"; print "

draw_map.js
Javascript code that creates and displays the Google map and storm tracks.

"; print "

storms.css
The site-specific CSS style sheets.

"; print "
"; // data object to access MySQL //$db = new PDO('mysql:host=localhost;dbname=storms_testing', 'stormy'); //$db = new PDO('mysql:host=localhost;dbname=historical_storms', 'stormy'); print "
"; print "
"; print "
"; print "

Name   Year Month Day   StormType

"; print "
"; print "
"; // TBD - it would be nice, when one selects one or more Years or Names, to have the other (Name or Year) selector // be limited to valid selections, eg. if I select years 2005 and 2007, have the Name selector suddenly contain only // the 43 valid names for those two years: // // "select distinct storm_name, year(date_time) from StormName as sn, TrackPoint as tp where sn.id = tp.storm_name_id // and tp.storm_id IN (SELECT DISTINCT storm_id FROM TrackPoint AS tp where (year(date_time) = '2005' or // year(date_time) = '2007')) order by storm_name" // // But such a database query can take several seconds, which might be confusing to the user. // May be possible to create a Year table for faster Name/Year joins. // // populate the storm name list // $rs = mysql_query('select distinct storm_name from StormHeader order by storm_name'); if (! $rs) { $error = mysql_error(); print "Problem: ($error)"; } print "\n"; // populate the storm year list // $rs = mysql_query('select MAX(YEAR(obs_date)) as max_year from StormObservations'); if (! $rs) { $error = mysql_error(); print "Problem: ($error)"; } if($fetch_year = mysql_fetch_object($rs)) { $max_year = $fetch_year->max_year; } print "\n"; // populate the storm month list // $monthArray = array(1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); print "\n"; // populate the storm day-of-month list // print "\n"; // populate the Saffir-Simpson storm type list // $storm_type_arr = array("Tropical Depression", "Tropical Storm", "Hurricane - Category 1", "Hurricane - Category 2", "Major Hurricane - Category 3", "Major Hurricane - Category 4", "Major Hurricane - Category 5", "Subtropical Storm", "Tropical Disturbance"); print "\n"; print "
"; // queryBuilderDiv $sql_loc = "SELECT DISTINCT loc_US,cat_loc_US " . "FROM StormHeaderLocUS " . "ORDER BY SUBSTRING(loc_US,-2),loc_US"; $res_loc = mysql_query($sql_loc); if (! $res_loc) { $error = mysql_error(); print "Problem: ($error)"; } print "
"; print "

U.S. location hit                 Category Hit             Basin

"; print "
"; print "
"; print "             "; print "               "; print ""; print "
"; print "
"; print "Distance: "; print ""; print " \n"; print ""; print " Latitude: "; print " \n"; print "Longitude: "; print "\n"; ?>