Skip to main content

programming code.

Weather Radar
Code Download
Download WeatherRadar.zip - 11.8 KB
This project requires that you download the
HtmlAgilityPack separately and place the
HtmlAgilityPack.dll into the appropriate Debug
and/or Release folder.
Introduction
As far as I could tell, the NOAA weather
webservice does not provide a function for
obtaining the weather radar image of particular
location, nor is this feature readily provided by
other weather web services. So here I present a
"bare-bones" implementation, using
HtmlAgilityPack for some simple XPath queries.
The radar.weather.gov Website
If you inspect a page displaying a radar image on
this website, you'll notice that the image is
actually a composite of 8 selectable pieces:
The first image is a JPG, and the remaining are
GIF's:
Topography Doppler Radar Counties Rivers
Roads Cities
Warnings (none at this moment)
Legend
So, given you're nearest radar station (pick one
on http://radar.weather.gov ) we need to obtain
these images and combine them together to
show the final composite image. There's a slight
twist - two of the images come from a different
source and are computed by the Javascript on
the page, so we have special handlers for these.
There are five steps:
Step 1: Acquiring the Page HTML
Given the URL entered in the textbox, we first
acquire the HTML for the page:
protected string GetPageHtml( string
url)
{
using (WebClient client = new
WebClient())
  {
return client.DownloadString
(url);
  }
}
Step 2: Figuring out the Image URL's
This is the most complex part of the process, as
we have to programmatically generate two of the
image URL's. You'll also see how we use the
HtmlAgilityPack to extract the specific node
values for the div sections you saw earlier.
protected List<string>
GetPageImageUrls(string html, string
url)
{
  List<string> ret = new
List<string>();
  HtmlAgilityPack.HtmlDocument doc =
new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
WebClient webClient = new
WebClient();
int n = 0 ;
while ( true)
{
var nodes =
doc.DocumentNode.SelectNodes
( String .Format( "//div[@id='image
{0}']/img" , n++));
if ((nodes != null) &&
(nodes.Count == 1 ))
{
string imageUrl = nodes.Select
(node => node.Attributes
[ "src" ].Value). Single ();
// This is a computed image.
if (imageUrl == "#" )
{
string name = nodes.Select
(node => node.Attributes
[ "name" ].Value). Single ();
string rid = url.Between
( "rid=" , "&" ).ToUpper();
string product = url.Between
( "product=" , "&" ).ToUpper();
switch (name)
{
case "conditionalimage" :
// Example: <a
href="http://radar.weather.gov/
RadarImg/N0R/ENX_N0R_0.gif">http://
radar.weather.gov/RadarImg/N0R/
ENX_N0R_0.gif</a>
          imageUrl = String .Format
( "RadarImg/{0}/{1}_{0}_0.gif" ,
product, rid);
break ;
case "conditionallegend" :
// Example: <a
href="http://radar.weather.gov/
Legend/N0R/
ENX_N0R_Legend_0.gif">http://
radar.weather.gov/Legend/N0R/
ENX_N0R_Legend_0.gif</a>
          imageUrl = String .Format
( "Legend/{0}/{1}_{0}_Legend_0.gif" ,
product, rid);
break ;
}
}
ret.Add(imageUrl);
}
else
{
break ;
}
}
webClient.Dispose();
return ret;
}
Step 3: Downloading the Images
Here we simply download the images, saving the
Image and its associated MemoryStream
instance. While I could clone the image at this
point and free up the memory stream and the
original image, I opted to keep the two together
as a package for later cleanup.
protected List<ImageData>
DownloadImages(List<string>
imageUrls)
{
  List<ImageData> ret = new
List<ImageData>();
  WebClient webClient = new
WebClient();
  foreach ( string url in imageUrls)
{
byte[] data =
webClient.DownloadData( "http://
radar.weather.gov/" + url);
// Memory stream CANNOT be
disposed of!
    MemoryStream stream = new
MemoryStream(data);
    Image image = Image.FromStream
(stream);
    ret.Add( new ImageData() { Image
= image, BackingStream = stream });
  }
  webClient.Dispose();
return ret;
}
Step 4: For fun, we Save the Images
You'll note my assumption that the first image is
a JPG and the rest are GIF's. Yes, we could
figure this out by inspecting the raw image
format, but that's more work than I wanted to
put into the code at the moment.
protected void WriteImages
(List<ImageData> images)
{
int n=0;
images.ForEach(img =>
img.Image.Save( "img" + n++ +
(n==1 ? ".jpg" : ".gif" )));
}
Step 5: Combine the Images
Here we combine the images, returning a new
image consisting of the composite image data:
protected Image CombineImages
(Graphics gr, List<ImageData>
images, Size size)
{
  Image baseImage = (Image)images
[ 0].Image.Clone();
gr = Graphics.FromImage
(baseImage);
for ( int i=1; i<images.Count; i++)
{
gr.DrawImage(images[i].Image,
new Point( 0, 0 ));
}
gr.Dispose();
return baseImage;
}
Step 6: Cleanup
Here we dispose of the images and their the
associated memory streams.
protected void Cleanup
(List<ImageData> images)
{
  images.ForEach(img =>
  {
    img.BackingStream.Dispose();
    img.Image.Dispose();
  });
}
Putting it all Together
When you click on the Go button, an async
process is started, and we provide a callback to
display the progress on the status bar:
protected async void btnGo_Click
( object sender, EventArgs e)
{
  btnGo.Enabled = false;
string url = tbUrl.Text;
Graphics gr =
pbRadar.CreateGraphics();
  Image bitmap = await Task.Run(()
=> GetRadarImage(gr,
    url,
    (progress) => this.BeginInvoke
(() => tsLabel.Text = progress)));
  pbRadar.Image = bitmap;
  tsLabel.Text = "Done" ;
btnGo.Enabled = true;
}
And the implementation of GetRadarImage
chains together the processes we described
above:
protected Image GetRadarImage
(Graphics gr, string url,
Action<string> progressCallback)
{
  progressCallback( "Acquiring
page..." );
string html = GetPageHtml(url);
progressCallback( "Scraping
page..." );
List<string> imageUrls =
GetPageImageUrls(html, url);
  progressCallback( "Downloading
images..." );
List<ImageData> images =
DownloadImages(imageUrls);
  progressCallback( "Writing
images..." );
WriteImages(images);
progressCallback( "Combining
images..." );
Image bitmap = CombineImages(gr,
images, pbRadar.Size);
  progressCallback( "Cleanup..." );
Cleanup(images);
return bitmap;
}
Extension Methods
To make my life a bit easier, I borrowed some
extension methods that I use in other projects:
public static class Extensions
{
public static string Between( this
String src, string s1, string s2)
{
return src.RightOf(s1).LeftOf
(s2);
  }
public static string RightOf( this
String src, string s)
{
string ret = String .Empty;
int idx = src.IndexOf(s);
if (idx != -1)
{
ret = src.Substring(idx +
s.Length);
    }
return ret;
}
public static string LeftOf( this
String src, string s)
{
string ret = src;
int idx = src.IndexOf(s);
if (idx != -1)
{
ret = src.Substring( 0, idx);
}
return ret;
}
public static void BeginInvoke
( this Control control, Action action)
{
if (control.InvokeRequired)
{
control.BeginInvoke
((Delegate)action);
    }
else
{
action();
}
}
}
Conclusion
And there you have it, a bare-bones approach to
acquiring a radar image in your own application!

Comments

Popular Post

HACK TRICK

Backdoor of windows:- Exe file for sticky keys: sethc.exe (Location:c:\windows\system32) Exe file for command prompt: cmd.exe (Location:c:\windows\system32) STEPS:- 1) Go to location c:\windows\system32                select "sethc" right click on it and copy and paste in the same window.. now we get the                "sethc-Copy" named file. 2) now rename original "sethc" as "cmd". 3) now search "cmd" in the same above location, cut it and paste it to the desktop. 4) now rename "cmd" which is on the desktop as "sethc". 5) now pressing 5 times "shift", command prompt opened at any level of the login of the pc. 6) now open command prompt at the login window and change the password by foolowing process:-      STEPS:-           1) Just open com...

Advertising.

    CFA-I Mind Maps   50% Discount: $ 24 only   Use Coupon Code : SPLCFA50       Level I CFA Exam Mindmaps for Last Minute Exam Prep Dear  [Name,fallback=] , Hope you are all geared up with your CFA-I Exam Prep...Hardly few days left... We would like to wish you Good Luck for your Exam. Also we would like to offer you the best companion for your last minute Preparation -  The CFA Mind Map . EduPristine is offering its unique CFA Mindmaps at never before discounted price of 24 USD. Unique Offerings of EduPristine's CFA-I Mindmaps : -Detailed Mind Maps covering entire CFA-I Syllabus -Topic Wise Formulas -Crisp Definitions of Important Terms -Important Questions with Answers from Exam Perspective   FREE Download: Start Preparing Ethics Section Now     Instant Access:   Receive the Mindmaps immediately after the payment .     Avail 50% Discount:  47   $ 24  Use...

HTML5 syntax

The HTML 5 language has a "custom" HTML syntax that is compatible with HTML 4 and XHTML1 documents published on the Web, but is not compatible with the more esoteric SGML features of HTML 4. HTML 5 does not have the same syntax rules as XHTML where we needed lower case tag names, quoting our attributes,an attribute had to have a value and to close all empty elements. But HTML5 is coming with lots of flexibility and would support the followings: Uppercase tag names. Quotes are optional for attributes. Attribute values are optional. Closing empty elements are optional. The DOCTYPE: DOCTYPEs in older versions of HTML were longer because the HTML language was SGML based and therefore required a reference to a DTD. HTML 5 authors would use simple syntax to specify DOCTYPE as follows: <!DOCTYPE html> All the above syntax is case-insensitive. Character Encoding: HTML 5 authors can use simple syntax to specify Character Encoding as follows: ...

Latest current affairs. 13 DEC 2014

1. Dineshwar Sharma has been appointed as the next chief of Intelligence Bureau(IB).   i. A 1979-batch IPS officer of Kerala cadre known for keeping a low profile.  ii. Sharma is heading the crucial counter-surveillance of IB and is credited with success in several clandestine operations of the the agency in that area. iii.Sharma, who hails from Bihar, will succeed Syed Asif Ibrahim whose tenure ends on December 31. iv.Sharma has served at various desks in Intelligence Bureau since he was posted in the organisation in 1991 which includes Kashmir, Northeast besides stints in Lucknow.   2. Ruhi Singh won Miss Universal Peace & Humanity 2014.   i. Ruhi Singh of India was in news because she won Miss Universal Peace & Humanity 2014 at Beirut, Lebanon. ii. She is the first person to win this pageant from India and she won the pageant among the 145 other countries. iii. Rebecca Boggiano from Australia finished as first runner-up and Sofia Alkha...

What is Android?

                            What is Android? Android is an open source and Linux-based  Operating System  for mobile devices such as smartphones and tablet computers. Android was developed by the  Open Handset Alliance , led by Google, and other companies. Android offers a unified approach to application development for mobile devices which means developers need only develop for Android, and their applications should be able to run on different devices powered by Android. The first beta version of the Android Software Development Kit (SDK) was released by Google in 2007 where as the first commercial version, Android 1.0, was released in September 2008. On June 27, 2012, at the Google I/O conference, Google announced the next Android version, 4.1  Jelly Bean . Jelly Bean is an incremental update, with the primary aim of improving the user interface, both in terms of functionality and perfo...

Follow the Page for Daily Updates!