Saturday, November 3, 2012

NEW - US National Weather Service geolocation lookup server

Just completed my first hack of a US National Weather Service (NWS) geolocation lookup server.

It doesn't tell you weather...instead it tells you the best Observation Station code and Forecast Zone code so your application can pull the right data directly from the NWS servers.

NWS lookup is important to US users for obvious reasons. Internationally, it's important, too - NWS is one of the easiest and most open sources of international METAR current-condition reports.

Proprietary services like wunderground,, and Yahoo! will feed weather data based on raw locations...but as the recent and sudden Google Weather shutdown showed us, it's good to keep more than one arrow in your quiver. And this doesn't require registration nor an API's totally free.

This lookup feature has been sorely lacking. In the past, you needed to scrape a NWS web page to figure out those codes...or ask the user to go find them somehow.


Here's an example of how to use the lookup: I have a zipcode (53207), and I need to know the appropriate Observation Station to get current conditions from:

$ wget -q -O - \
               | sed 's/.*<station_code>\(.*\)<\/station_code>.*/\1/'


The local station is 'kmke'. Plug that into the NWS current conditions URL:

$ wget -q -O -

Nov 03, 2012 - 06:52 PM EDT / 2012.11.03 2252 UTC
Wind: from the NE (040 degrees) at 6 MPH (5 KT):0
Visibility: 10 mile(s):0
Sky conditions: mostly cloudy
Temperature: 39.0 F (3.9 C)
Dew Point: 30.0 F (-1.1 C)
Relative Humidity: 69%
Pressure (altimeter): 30.19 in. Hg (1022 hPa)
ob: KMKE 032252Z 04005KT 10SM FEW035 SCT120 BKN250 04/M01 A3019 RMK AO2 SLP231 T00391011
cycle: 23

How to use it

The lookup testing server at accepts 5-digit zipcodes (53207), three-letter airport codes(mke), place names (Milwaukee,WI), and lat/lon (lat=42.57n,lon=87.54w). Lat/Lon is available worldwide, and will return the closest METAR location, the rest are US-only.,CA,lon=32.443E

It returns an XML string. The string includes three sections: A data_source credit, the original parsed request, and the location data with the Observation Station code (kmke), a descriptive location string (General Mitchell International Airport, WI), and a Forecast Zone code (wiz066). Non-US METAR sites lack the Forecast Zone, since NWS creates forecasts for the US only.

  <data_source>weather-util data files, Oct 25, 2012, v2.0,</data_source>
    <station_location>Entebbe Airport, Uganda</station_location>

Limitations on name searches

Some large city requests (City,St) may return multiple locations, or unexpected results since the city may have multiple observation stations or multiple forecast zones within the boundaries. This is a limitation of the public data sets. For example, a search for /place/New+York+City,NY will return an error, since that's not really the city's name. A search for /place/Brooklyn,NY will return a closest Observation Station at Central Park instead of Kennedy Airport. Zipcode searches will generally return more accurate results.

Usage limits

The testing server is limited to five requests per day, so cache those results! Or just contact me if you want to be on the 'unlimited' list. Throttling is merely to spare my server from abuse - it's not meant to be a tease.

Give it a try, and let me know what you think.
If you find a bug, please e-mail me instead of leaving a comment.

Data sets and Credits

The dataset is merely the weather-util-data package, a set of reformatted and correlated lookup tables of freely-available US Government geospatial information. This USG public data is available for public use without copyright or restriction.

Thanks to the US National Weather Service for public access to so many cool products.

Special thanks to Jeremy Stanley, developer of the weather-util* packages, who created most of the important geolocation code and figured out a way to create the lookup tables. I merely wrapped an XML server around those tables. His code is released under the ISC license, which is GPL-compatible, and authorizes reuse.

Source code for this 0.0.1 (still hacking) version is at, since I haven't actually organized a project around this script yet.

No comments: