[January 2, 2012 Update: A number of changes have been made to the NDFD web service since I originally posted this article. Both the URL and the methods exposed by the service have changed. The text below and downloads have been updated to reflect these changes.]
Unlike weather forecasts which are available for any point in the US, current conditions are only available for specific spots where there are reporting stations. The good news is that there are more than 2000 reporting stations, so it’s not too hard to find one close to you. In this installment I am going to add the ability to get the current weather conditions to our library of weather tools. (If you are following along in this series, you will notice I have done a bit of mild refactoring, getting ready for the next steps – a local Windows “weather” service and a real desktop UI).
As usual, the folks at the National Weather Service have made our job pretty easy. You can take a look at what they’ve given us to work with here. Each observation stations get its own web page containing an Xml document (updated hourly) describing the current weather conditions. The URL for the page containing the current conditions for each weather station is formed by appending the station’s identification string to the base URL for current observations. So for example to get the current conditions for Smithfield, Rhode Island the URL would look like this:
So now the puzzle comes down to how do we find the ID for the reporting station closest to the spot for which we want the current conditions? We’ve got a few choices, but all of them start with this document, the index of reporting stations. It contains an entry for every reporting station, formatted just like this excerpt for our Smithfield station:
<station> <station_id>KSFZ</station_id> <state>RI</state> <station_name>Smithfield</station_name> <latitude>41.91</latitude> <longitude>-71.4</longitude> <html_url>http://weather.noaa.gov/weather/current/KSFZ.html</html_url> <rss_url>http://weather.gov/xml/current_obs/KSFZ.rss</rss_url> <xml_url>http://weather.gov/xml/current_obs/KSFZ.xml</xml_url> </station>
The key pieces here are the station_name, state and station_id. We’re also going to find the latitude and longitude useful a bit later. Since this is a reasonably large document (900kb) and we want to play really nice with the NWS folks so they’ll let us continue to use their toys (and we want our app to be responsive), we’ll download it once (using a BackgroundWorker) and cache a copy in IsolatedStorage (along with an option to refresh our cache when needed).
So armed with the list of all the reporting stations, there are a couple of routes we could take. On the one hand we could simply mimic what the NWS does on their current conditions web page:
- Show the user a list of all the states and ask them to pick one.
- Based on their selection, show them a list of all the observation stations in that state and ask them to pick one.
- From their selection, compose the URL for the current conditions page and submit a web request.
The TestFromStateStation sample application (available for download at the end of this post) implements this approach.
The other approach is to:
- Ask the user for the Zip Code for their location.
- Query the NDFD web service for a location (latitude, longitude) associated with the zip code.
- Compute the distance between the zip location and the location of each observation station in the reporting stations index (see above) to find the closest station.
- Use the station Id from the closest station to compose the URL for the current conditions page and submit a web request.
This technique relies on being able to determine the distance between two points on the earth’s surface. There are a number of techniques we can use – you can read a really good description of your options thanks to the folks at movable-type. For our purposes, the spherical law of cosines is good enough (see ObservationStations.GetDistance() in the NationalWeatherServiceLibrary project in the attached solution). The TestFromZip sample (see below) implements this approach.
So there you have it, the ability to get the current weather conditions using either state/station or zip code. As promised, here are the downloads: TestFromStateStation.exe, TestFromZip.exe and the complete VS2010 solution.
At this point we’re done with the web service pieces of the project; we know how to get forecasts and current conditions for anywhere in the US. Next it’s time to create the UI.