Bill Tudor

Weblog

  Home  |   Contact  |   Syndication    |   Login
  49 Posts | 0 Stories | 95 Comments | 0 Trackbacks

News

Copyright © Bill Tudor

Archives

Post Categories

I recently needed to create a web service to provide coastal tidal predictions, i.e., the low tide and high tide times for a given day at a given location.

The Web Service

I decided to forego a traditional “web service” and provide a calendar feed (using iCalendar data format) instead. This approach allows devices such as an iPod Touch (or iPhone), as well as most internet-aware calendar programs, to grab and display the data on a calendar – perfectly appropriate for this kind of information. Internet-based calendars, such as google calendar, can also grab and display the feed. The service is designed to provide 30 days worth of data beginning with the current day.

The Data Source

The best source for this type of data in the US is the often overlooked National Oceanic and Atmospheric Administration (NOAA). When it comes to weather, the National Weather Service arm of NOAA provides a slew of web service products for your programs to consume. For tidal data, however, not so lucky. I was stuck with HTTP-page-scraping or FTP file transfers – yuk. Ugly, but doable. A quick peek at the format of the HTML served up by NOAA’s tidal prediction web site reveals that they most likely store data in a simple text file (for ftp-based access), and simply pump this out inside of a HTML element for HTTP access. A year’s worth of predictions is stored in the page. I don’t know when the “next year” is made available, but since I am much more interested in tidal data for the summer months, I’m not concerned with how well the service will perform over the Dec-Jan timeframe. The data is easy to scrape with a regular expression.

Using Regular Expressions

The following regular expression was used to scrap the data from NOAA’s web page:

private static Regex _reg = new Regex(@"((?<date>\d{1,2}/\d{1,2}/\d{4})\s+\w+)?\s+(?<time>\d{1,2}:\d{2}(A|P)M)\s+(LST|LDT)\s+(?<height>[-\+\d\.]+)\s+(?<tide>(L|H))");
 

The date and time of the predictions, as well as the type (Low or High), and the height (which I don’t use) are captured from the expression. NOAA uses local time, which they indicate with the LST or LDT monikers – I will simply assume all times are local for the given date, which was correct for this year’s data, anyway.

Grabbing the Web Page

It’s quite easy to grab a page via HTTP these days:

WebRequest request = null;
WebResponse response = null;
Stream responseStream = null;
try
{
    request = WebRequest.Create(uriString);
    response = request.GetResponse();
    responseStream = response.GetResponseStream();
    if (responseStream.CanRead)
    {
        using (StreamReader sr = new StreamReader(responseStream))
        {
            string data = sr.ReadToEnd();
            return CreateFromData(data, startDate, endDate);
        }
    }
}
finally
{
    if (responseStream != null) responseStream.Close();
    if (response != null) response.Close();
}

The CreateFromData() method simply walks through the regular expression matches to build a list of NOAATidePrediction objects:

public static NOAATidePredictions CreateFromData(string data, DateTime startDate, DateTime endDate)
{
    NOAATidePredictions result = new NOAATidePredictions();
    DateTime date = DateTime.MinValue;
    foreach (Match m in _reg.Matches(data))
    {
        if (m.Groups["date"].Success)
        {
            date = DateTime.Parse(m.Groups["date"].Value);
        }
        if (date != DateTime.MinValue &&
            date >= startDate &&
            date <= endDate
            )
        {
            TidePrediction.TideType t = TidePrediction.TideType.High;
            if (m.Groups["tide"].Value == "L")
            {
                t = TidePrediction.TideType.Low;
            }
            DateTime time = DateTime.Parse(m.Groups["time"].Value);
            result.Tides.Add(new TidePrediction(date.AddMinutes(time.TimeOfDay.TotalMinutes), t, double.Parse(m.Groups["height"].Value)));
        }
    }
 
    return result;
}

Not all of the code is shown here, but it is pretty easy to figure out what the NOAATidePredictions and TidePrediction classes, for example, look like.

Converting the TidePrediction objects to iCalendar events is pretty easy as well (also not shown) since we are only creating simple events for each tide prediction.

Serving up the Calendar Feed

I already have an HTTPHandler on my web site that gets invoked when “*.ics” files are requested. A request to “tides.ics”, along with the location information, now serves up the data – courtesy of NOAA – created on the fly from the code shown above.

Not bad for a few hours work. With a quick glance at my iPod Touch, I can view the high/low tide times for the next 30 days on it’s calendar.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Friday, July 31, 2009 6:23 AM