Locate the Nearest Radar Station and Display Radar Images
Published: January 2nd, 2009 by: Andrew
Including up-to-date radar images on your website is easier than you might think. In this article, I am going to share where you can get radar images for free for US radar sites and even share some sample code that will fetch the closest radar site by lat/lon and display it on your website.
Using Radar Images from Individual NEXRAD Radar Sites
Most of the radar data that you are going to need can be found here: http://radar.weather.gov/ridge/RadarImg/
The radar images are first sorted by the type of radar images you are looking for. Here is what all those codes mean:
- N0R = Reflectivity (most commonly used)
- N1P = 1 Hour Precipitation
- NTP = Storm Total Precipitation
- N0V = Velocity
- N0S = Storm Relative Motion
- N0Z = Long Range Reflectivity
If you don’t know what the different radar types are, the most common one used (like on TV, etc) is “Reflectivity”, or N0R.
If you start browsing the directories, you will notice that it is the radar data only. No county lines, state lines, rivers, etc. Those maps have to be merged in separately. That data is to be downloaded at this URL: http://radar.weather.gov/ridge/Overlays/. Current severe weather warnings are also available as an additional layer. This data can be found at http://radar.weather.gov/ridge/Warnings/Short/.
Putting the maps together are not hard. They are layered on top of each other with some CSS. Below is an example. You may want to move the inline CSS code to an external stylesheet.
<div style="position: relative; left: 0; top: 0; height: 550px; width: 600px;"> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:0" src="http://radar.weather.gov/Overlays/Topo/Short/LOT_Topo_Short.jpg" alt="" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:1" id="radar_image" src="http://radar.weather.gov/RadarImg/N0R/LOT_N0R_0.gif" height="550" width="600" alt=""/> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:2" src="http://radar.weather.gov/Overlays/County/Short/LOT_County_Short.gif" alt="" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:3" src="http://radar.weather.gov/Overlays/Highways/Short/LOT_Highway_Short.gif" alt="" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:4" src="http://radar.weather.gov/Overlays/Rivers/Short/LOT_Rivers_Short.gif" alt= "" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:5" src="http://radar.weather.gov/Overlays/Cities/Short/LOT_City_Short.gif" alt="" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:6" id="radar_legend" src="http://radar.weather.gov/Legend/N0R/LOT_N0R_Legend_0.gif" name="conditionallegend" alt="" /> </div> <div style="position: absolute; left: 0; top: 0;"> <img style="z-index:7" src="http://radar.weather.gov/Warnings/Short/LOT_Warnings_0.gif" border="0" alt="" /> </div> </div> <!-- radarmap -->








More information can be found here: http://www.srh.noaa.gov/jetstream/doppler/ridge_download.htm
Finding a Radar Site’s Location
So far, this is nothing too challenging. No PHP is needed up to this point, as we are just displaying some images. There are times, however, when one doesn’t know which radar site to use. In a recent project, I had to find the closest radar site based on a lat/lon location, not the station name. In order to do this, we need to know the location of each and every radar site. The NWS provides ‘GIS’ files for each radar site that is supposed to be for radar programs to read. We will use this information to plot a map of radar sites.
Each radar site has it’s own GIS file. If you browse the directory at http://radar.weather.gov/RadarImg/N0R/, you will find a .gfw file for each radar site. You will need to parse every one of those files, based on the specs, found here. Luckily, I already did the hard work, and you can reap the results of my labor by importing the data using either of these two files.
Note: These lat/lon coordinates are not for the center points of the map. Don’t ask me why, but they are for the top-left corner of the map. If you want the center, you will have to offset the lat/lon by about 3 degrees, as you will see me do in the later examples.
Query for the Closest One
Very rarely will the application know the exact location of the radar site. Most of the time, the application will be provided with a lat/lon pair, and it is up to the developer to find the closest station based on that provided location. This can be accomplished with a little math in a SQL query.
-- (PHP code to provide $lat and $lon variables) -- SELECT *, SQRT(POW(69.1 * (lat - $lat), 2) + POW(69.1 * ($lon - lon) * COS(lat / 57.3 ), 2 )) AS distance FROM RadarSites ORDER BY distance ASC LIMIT 1
In addition to the table fields, we have an additional dynamic field called ‘distance’ which represents the distance from the radar sites. Sort the results by distance, and voilla, we have the closest radar site.
Using Radar Maps with IP Geolocation
In a previous article, I covered how to get the location of any IP address. I will combine that with this article and provide an example that will show the radar images for the radar site closest to you. If you are not located in the US, then you will see a radar site somewhere on the US coast.
<?php /* replace with your own DB connection code */ require('../includes/database.php'); $db = db_connect(); /* get the IP address and make sure it is an unsigned integer */ $ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR'])); /* fetch the location id */ $query = "SELECT locId FROM CityBlocks WHERE $ip BETWEEN startIpNum AND endIpNum LIMIT 1"; $result = mysql_query($query, $db) or die(mysql_error()); $row = mysql_fetch_assoc($result); /* now fetch the location */ $locId = $row['locId']; $query = "SELECT * FROM CityLocation WHERE locId = $locId LIMIT 1"; $result = mysql_query($query, $db) or die(mysql_error()); $location = mysql_fetch_assoc($result); /* offset the coordinates by 3, and find the closest station */ $lat = $location['latitude'] + 3; $lon = $location['longitude'] - 3; $query = "SELECT *, SQRT(POW(69.1 * (lat - $lat), 2) + POW(69.1 * ($lon - lon) * COS(lat / 57.3 ), 2 )) AS distance FROM RadarSites ORDER BY distance ASC LIMIT 1"; $result = mysql_query($query, $db) or die(mysql_error()); $radar = mysql_fetch_assoc($result); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>IP Geolocation Example</title> <meta name="generator" content="Bluefish 1.0.7"> <meta name="author" content="Andrew Wells"> <meta name="date" content="2008-12-26T17:05:21-0600"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8"> </head> <body> <div style="position: relative; left: 0; top: 0; height: 550px; width: 600px;"> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:0" src="http://radar.weather.gov/Overlays/Topo/Short/<?=$radar['id']?>_Topo_Short.jpg" alt="" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:1" id="radar_image" src="http://radar.weather.gov/RadarImg/N0R/<?=$radar['id']?>_N0R_0.gif" height="550" width="600" alt=""/></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:2" src="http://radar.weather.gov/Overlays/County/Short/<?=$radar['id']?>_County_Short.gif" alt="" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:3" src="http://radar.weather.gov/Overlays/Highways/Short/<?=$radar['id']?>_Highway_Short.gif" alt="" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:4" src="http://radar.weather.gov/Overlays/Rivers/Short/<?=$radar['id']?>_Rivers_Short.gif" alt= "" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:5" src="http://radar.weather.gov/Overlays/Cities/Short/<?=$radar['id']?>_City_Short.gif" alt="" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:6" id="radar_legend" src="http://radar.weather.gov/Legend/N0R/<?=$radar['id']?>_N0R_Legend_0.gif" name="conditionallegend" alt="" /></div> <div style="position: absolute; left: 0; top: 0;"><img style="z-index:7" src="http://radar.weather.gov/Warnings/Short/<?=$radar['id']?>_Warnings_0.gif" border="0" alt="" /></div> </div> <!-- radarmap --> <h2>Details on IP Location:</h2> <pre><?php var_dump($location); ?></pre> <h2>Details on Radar Site Location:</h2> <pre><?php var_dump($radar); ?></pre> </body> </html>
More Ways to Find the Location
There are plenty of other ways to get the lat/lon coordinates needed to find the nearest radar site. If you want to find it by ZIP code, the National Weather Service offers a zip code to lat/lon product as part of their National Data Forecast Database. Lat/lon coordinates can also be retrieved from a street address using Google’s Reverse Geocoding service.
Michael Dupuis
Feb 25th, 2009
7:24 am
Is the equation to find the closest station correct? I ask because I can’t seem to get it to return the closest stations to a specified location for me. It will return a close location, but not the closest one. For example, if I use the the location for Lewiston, ME (44.09°N 70.19°W) I get BOX as the nearest station, instead of GYX, which is what I’d expect (Boston is about 120 miles from this location, Gray is only 15 miles). GYX is actually listed as the second closest. I can’t figure out what could account for this. I notice similar problems with other locations (like San Francisco, which seems to return the LA station, not the one nearest to San Francisco).
Andrew
Feb 25th, 2009
8:09 am
Hi Michael, can you post the queries that you are running? I copied your locations into one of my weather sites, and I am getting the correct station back.
Remember, you have to offset your location by ~3 degrees because that radar location database is for the top-left corner of the radar coverage, and you want the center.
Michael Dupuis
Feb 25th, 2009
8:38 am
Well I can’t do this in a query, because I’m using SQLite, so I’m doing this in code. The equation is sqrt((pow(69.1 * (lat – 44.09),2) + pow(75.1 * (-70.19 – long)*cos((lat/57.3)),2))) with the lat and long filled in for each row of course, and the values not offset. I saw your note about the offset of 3 degrees, and tried to do that, but I think I’m just misunderstanding how that should work, as doing that didn’t fix things either. Sorry if I’m missing something simple here (I clearly am). Thanks
Andrew
Feb 25th, 2009
8:55 am
So you are adding 3 to the latitude and subtracting 3 from the longitude and it’s still not working?
Can’t help you with the SQLite part, but I know you have to make the calculation in the query, because the distance is different for each query.
Michael Dupuis
Feb 25th, 2009
10:01 am
Ok, you know… I could have sworn I tried that, and did that correctly, but I must not of. Trying it again, it seems to be working fine. Thanks for clearing that up. I must have messed something up when I tried it before, sorry for the confusion, because if you do the add 3/subtract 3 it works correctly. One of those days I guess. 🙂
Jkirby
Apr 18th, 2009
6:21 pm
Andy-
This is very cool. I have adapted this to also build in a Java 2D application. Do you know how to get the “looping” radar to work?
mike
Jul 10th, 2009
7:53 am
any idea how to use PHP to stack everything into a single image? Mine just turns darker with each overlay addition.
Andrew
Jul 17th, 2009
2:44 pm
mike: see http://phpstarter.net/2009/07/merge-image-layers-in-php/
mike
Nov 6th, 2009
2:32 pm
Andrew, have you tried or have any tips on marking a particular point on these images? I’m thinking along the lines of a generated overlay to mark a particular geo location. If I’m thinking correctly, the Lat calc should be consistent, but the Lon calc will differ depending on the Lat.