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

Current affairs

Narendra Ambwani elected as chairman of the Advertising Standards Council of India (ASC Published on: 13-SEP-2014 Important for Exam:  6 people agreed Narendra Ambwani on 12 September 2014 elected as Chairman of the Advertising Standards Council of India (ASCI). SBI celebrated 150 years of its operations in Sri Lanka Published on: 13-SEP-2014 Important for Exam:  6 people agreed State Bank of India (SBI) on 13 September 2014 celebrated 150 years of its operations in Sri Lanka. West Bengal cabinet cleared farmer-friendly project Sech-Bandhu Prakalpa to boost irrigation Published on: 13-SEP-2014 Important for Exam:  8 people agreed The West Bengal cabinet on 12 September 2014 cleared a farmer-friendly project named  Sech-Bandhu Prakalpa  to boost irrigation. Delhi Government to charge cess of one rupee on cigarette and liquor to promote public tra Published on: 13-SEP-2014 Important for Exam:  5 people agreed ...

📍 DIFFERENCE BETWEEN FDI and FPI

  DIFFERENCE BETWEEN FDI and FPI #Stockmarket 💡 FDI is involved in setting up firms to produce goods and services. That is why it is called 'direct' institution. FPI on the other hand buys financial assets for profits. In order to remove the ambiguity that prevails on what is Foreign Direct Investment (FDI) and what is Foreign Institutional Investment (FII), it was decided to follow the international practice and lay down a broad principle that, where an investor has a stake of 10 percent or less in a company, it will be treated as FII and, where an investor has a stake of more than 10 percent, it will be treated as FDI. 💡 Since the source of funds is not revealed, the PNs are potentially unsafe. Therefore, SEBI imposed certain conditions like limits on the PNs that a single FII can issue, etc. SEBI wants the PN holders to register with SEBI and invest directly as India is a long-term growth story. SEBI policy paid off with the number of FIIs registering with the regulator go...

■ Can India Become A Technology Leader? India

  ■ Can India Become A Technology Leader?   ✅India is presently not a major player in the field of technology due to certain challenges and on the other side, there are many celebrated Indian technologists around the world as many of the technology giants choose an India- born techie as their leader. ✅The conversation around Indian executives at the helm of top tech companies has gathered some momentum with Parag Agrawal taking over as Twitter CEO. The major technology companies like Google and its parent company Alphabet, Microsoft and Twitter, Adobe and IBM are all headed by Indians. ● The Case of the U.S: ✅The Indian immigrants in the U.S are the part of the most educated and professionally accomplished communities in that country. ✅As of 2019, there were 2.7 million Indian immigrants in the U.S. ✅The government of the U.S has been instrumental in the triumphs of enterprise and the free market. ✅The governmental agencies have been actively supporting the research and develo...

World famous event

1. Walmart to open new store in India after 2-year gap  i. After a gap of two years, US retail major Walmart will open a new cash and carry store in Agra as it returns focus on India.  ii. The company, which opened its last store in Bhopal towards the end of 2012, has said it will focus on cash and carry business in India in the absence of clarity on FDI in multi-brand retail trade. iii. "Walmart is committed to India and we are focused on our growth plans... We have recently received all internal approvals for opening a new store in Agra, our second one in the city," Walmart spokesperson told PTI. 2. Jyotsna Suri elected as the President of the FICCI i. Jyotsna Suri, Chairperson of Bharat Hotels, on 20 December 2014 was elected as the President of the Federation of Indian Chambers of Commerce & Industry (FICCI). ii. Suri succeeded Sidharth Birla. iii. Alok B Shriram, deputy managing director of DCM Shriram Industries Ltd, assumed the charge of the presid...

Serial Blasts In SRI LANKA

Serial blasts across Sri Lanka Mains-GS-3-Security 1. Over 200 people were killed and nearly 500 injured in a series of blasts that shook Sri Lanka on Easter Sunday. 2. Churches and luxury hotels were targeted in the deadliest incidents since the civil war ended a decade ago. 3. Eight blasts occurred in and around the capital Colombo and in the eastern city of Batticaloa when large groups gathered at churches for Easter services. 4. Most of the blasts appear to have been suicide bombings. No group has claimed responsibility for the blasts. 5. Investigating authorities in Sri Lanka are yet to disclose the names of the suspects or the alleged perpetrators. 6. The scale and savagery of the attacks that clearly targeted Christians have left Sri Lankans devastated. Curb on Social Media 1. Sri Lankan law enforcement have urged the public to stay indoors following series of blasts. 2. Sri Lankan government blocked social media platforms like Facebook and Instagram to prevent the sp...

Follow the Page for Daily Updates!