Content
This application just connect to weather.noaa.gov every hour to retreive weather information.
All the information is in a string like "TFFR 281000Z 00000KT 9999 FEW020
19/18 Q1011 NOSIG" called METAR. (Information on metar decoding can be
found at http://www.nws.noaa.gov/oso/oso1/oso12/fmh1/fmh1toc.htm)
So we just parse this string using regular expression to find weather information (temperature, wind, pressure ...). After we retreive all
information we just show image associated with weather conditions and make a report containing all these informations.
project contents:
- class metar used for the parsing : only a big parsing of regular expressions
- ereg : use of microsoft regular expression functions to work like the php one's
- class used to store decoded weather informations : clouds, humidity, precipitation, runway, temp, visibility, weather, wind
- class to convert easily value : wind, pressure, temperature, length, height, windspeed
- xml_access : used for xml serialization for options and languages. It is used to save/restore object value in/from xml files
- tcp_socket : class to retreive data on the Internet (part of the network stuff project available on this website)
- class metar download : launch download every hour or retry download 5 min after a failure
- forms for user interface
- other utility class (file_access, Xp Style)
Most impotant points:
The php ereg function emulation
We just try to make similar function as the php one's to avoid changing too mutch the parsing.
public class ClassEreg
{
public static bool ereg(string pattern,string input_string,ref string[] strregs)
{
if (input_string=="")
return false;
if (!System.Text.RegularExpressions.Regex.IsMatch(input_string,
pattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase)
)
return false;
System.Text.RegularExpressions.Match m=System.Text.RegularExpressions.Regex.Match(input_string,
pattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase
);
strregs=new string[m.Groups.Count];
for (int cpt=0;cpt<m.Groups.Count;cpt++)
{
if(m.Groups[cpt].Captures.Count >0)
strregs[cpt]=m.Groups[cpt].Captures[0].Value;
else
strregs[cpt]="";
}
return true;
}
public static bool ereg(string pattern,string input_string)
{
return System.Text.RegularExpressions.Regex.IsMatch(input_string,
pattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase
);
}
}
These functions are called during all the parsing (the metar class is only a long boring parsing).
Here's a sample of use:
string[] regs=null;
string part="010V090";
if (ClassEreg.ereg("^([0-9]{3})V([0-9]{3})$", part,ref regs))
{
this.wind.direction.var_beg = System.Convert.ToDouble(regs[1]);
this.wind.direction.var_end = System.Convert.ToDouble(regs[2]);
}
Dynamic image loading
We use PictureBox and it's property PictureBox.Image to show images in forms.
private System.Windows.Forms.PictureBox picturebox_weather;
public void set_img_weather(string fullpath)
{
Image img=get_image(fullpath);
if (img!=null)
this.picturebox_weather.Image=img;
}
private Image get_image(string fullpath)
{
try
{
return Image.FromFile(fullpath);
}
catch
{
MessageBox.Show( "File "+fullpath+" not found.","Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
return null;
}
}
Dynamic image loading for notify icon
private System.Windows.Forms.NotifyIcon notify_icon;
string img_path="image.png";
if (this.components==null)
this.components = new System.ComponentModel.Container();
notify_icon=new System.Windows.Forms.NotifyIcon(this.components);
notify_icon.Icon=System.Drawing.Icon.FromHandle(this.GetThumb(new Bitmap(img_path),16,16).GetHicon());
Text for notify icon
private void drawstring_in_notify_icon(string text,NotifyIcon notify_icon)
{
Bitmap bitmap = new Bitmap( 16, 16,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics graphics = Graphics.FromImage(bitmap);
System.Drawing.Font drawFont = new System.Drawing.Font("Arial Narrow",8,System.Drawing.FontStyle.Regular);
string drawString = text;
SizeF drawStringSize = new SizeF();
drawStringSize = graphics.MeasureString(drawString, drawFont);
System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(Color.FromArgb( 255, 255, 255, 255));
graphics.DrawString(drawString, drawFont, drawBrush, 16/2-drawStringSize.Width/2,16/2-drawStringSize.Height/2);
notify_icon.Icon=System.Drawing.Icon.FromHandle(bitmap.GetHicon());
drawFont.Dispose();
drawBrush.Dispose();
graphics.Dispose();
}
Xml loading/Saving
The trick is the same for options,
language and language interface xml files. We just use xml
serialization. The following sample is for the options class
public static ClassOptions load(string config_file_name)
{
try
{
return (ClassOptions)XML_access.XMLDeserializeObject(config_file_name,typeof(ClassOptions));
}
catch
{
return new ClassOptions();
}
}
public bool save(string config_file_name)
{
try
{
XML_access.XMLSerializeObject(config_file_name,this,typeof(ClassOptions));
return true;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message,
"Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error
);
return false;
}
}
Where the xml serialization class is the following :
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public class XML_access
{
public static void XMLSerializeObject(string filename,object obj,System.Type typeof_object)
{
Stream fs=null;
try
{
XmlSerializer serializer = new XmlSerializer(typeof_object);
fs = new FileStream(filename, FileMode.Create,System.IO.FileAccess.ReadWrite );
XmlWriter writer = new XmlTextWriter(fs,System.Text.Encoding.Unicode);
serializer.Serialize(writer, obj);
writer.Close();
fs.Close();
}
catch(Exception e)
{
if (fs!=null)
fs.Close();
System.Windows.Forms.MessageBox.Show(e.Message,
"Error",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error
);
}
}
public static object XMLDeserializeObject(string filename,System.Type typeof_object)
{
XmlSerializer serializer = new XmlSerializer(typeof_object);
FileStream fs = new FileStream(filename, FileMode.Open);
XmlReader reader = new XmlTextReader(fs);
object obj;
obj = serializer.Deserialize(reader);
reader.Close();
fs.Close();
return obj;
}
}
|
|