Requirements:
- Microsoft Visual C# Express (2005 or 2008) or Microsoft Visual Studio 2005/2008
- Internet Access
- Basic knowledge using XML and C#
Getting weather conditions using the Google Weather API is quite easy, once you get the basics. This specific API is free to use and available everywhere, where there is an active Internet connection.
Let's take a look at the basics of the Google Weather API. The API calls are made through a direct HTTP request or by reading an XML document generated on the fly, depending on the location. The URL that reads the request is the following:
http://www.google.com/ig/api?weather=LOCATION
The LOCATION parameter is the location you want to get weather conditions for. A good think about the way the location is specified is the fact that it is not case sensitive or requiring a specific format. For example, if you want to get the weather for Chicago, you can use either of these parameter values:
Chicago
chicago
chicago il
Chicago, IL
60669
cHiCaGo
Although the last one seems a bit out of line, it will still be accepted and you will get correct results.
The returned data is pure XML, like this:
<?xml version="1.0" ?> <xml_api_reply version="1"> <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0"> <forecast_information> <city data="Chicago, IL" /> <postal_code data="60669" /> <latitude_e6 data="" /> <longitude_e6 data="" /> <forecast_date data="2010-02-04" /> <current_date_time data="2010-02-04 14:41:48 +0000" /> <unit_system data="US" /> </forecast_information> <current_conditions> <condition data="Cloudy" /> <temp_f data="27" /> <temp_c data="-3" /> <humidity data="Humidity: 79%" /> <icon data="/ig/images/weather/cloudy.gif" /> <wind_condition data="Wind: SE at 7 mph" /> </current_conditions> <forecast_conditions> <day_of_week data="Thu" /> <low data="31" /> <high data="35" /> <icon data="/ig/images/weather/cloudy.gif" /> <condition data="Cloudy" /> </forecast_conditions> <forecast_conditions> <day_of_week data="Fri" /> <low data="29" /> <high data="35" /> <icon data="/ig/images/weather/snow.gif" /> <condition data="Snow Showers" /> </forecast_conditions> <forecast_conditions> <day_of_week data="Sat" /> <low data="21" /> <high data="31" /> <icon data="/ig/images/weather/cloudy.gif" /> <condition data="Cloudy" /> </forecast_conditions> <forecast_conditions> <day_of_week data="Sun" /> <low data="21" /> <high data="27" /> <icon data="/ig/images/weather/cloudy.gif" /> <condition data="Cloudy" /> </forecast_conditions> </weather> </xml_api_reply>
The data you get returned for the specified location is very basic (compared to other weather API services) but it is more than enough for simple applications and applications that only need a couple of weather indicators. Here is what you get:
General information:
- The full city name, as registered at Google
- Forecast date and time (current)
- The unit system that is used for the returned data
For the current day:
- Current weather conditions
- Temperature (degrees Fahrenheit)
- Temperature (degrees Celsius)
- Humidity percentage
- Conditions icon (a small GIF image)
- Wind conditions
For the next four days (from the current day):
- The weather conditions
- Conditions icon (same format as for the current day)
- Highest temperature (degrees Fahrenheit)
- Lowest temperature (degrees Fahrenheit)
As you see, it really is pretty basic. Now let's get to actual work and try getting the data in a C# application. I am going to show this on a basic example of a console application (it keeps you focused on the coding rather than the UI at this point).
Start Visual C# Express (or Visual Studio) and create a C# Console Application. I named mine gwapi_sample (which stands for Google Weather API sample). You can name yours whatever you like - it doesn't matter at this point.

Now, create a new Class file and name it Weather.cs. It will contain all the functions and other classes that will be used to get the weather conditions.

The class file contents should look similar to this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace gwapi_sample { class Weather { } }
We're going to add another class to this file, the Conditions one. This specific class will store the conditions for a single API call. This is more convenient, than operating with separate strings that will store the data from a specific XML node.
Here is what you need to add right after class Weather {}:
public class Conditions { string city = "No Data"; string dayOfWeek = DateTime.Now.DayOfWeek.ToString(); string condition = "No Data"; string tempF = "No Data"; string tempC = "No Data"; string humidity = "No Data"; string wind = "No Data"; string high = "No Data"; string low = "No Data"; public string City { get { return city; } set { city = value; } } public string Condition { get { return condition; } set { condition = value; } } public string TempF { get { return tempF; } set { tempF = value; } } public string TempC { get { return tempC; } set { tempC = value; } } public string Humidity { get { return humidity; } set { humidity = value; } } public string Wind { get { return wind; } set { wind = value; } } public string DayOfWeek { get { return dayOfWeek; } set { dayOfWeek = value; } } public string High { get { return high; } set { high = value; } } public string Low { get { return low; } set { low = value; } } }
Basically, it is nothing more than a class with a set of properties. This class doesn't have any functions that perform specific actions or return values.
Add a reference to the System.Xml namespace, as we will be using it to get the XML data:
using System.Xml;
Now, let's add a function to the Weather class in the Weather.cs file that will get the conditions for a location, that is passed as a string to the function:
/// <summary> /// The function that returns the current conditions for the specified location. /// </summary> /// <param name="location">City or ZIP code</param> /// <returns></returns> public static Conditions GetCurrentConditions(string location) { Conditions conditions = new Conditions(); XmlDocument xmlConditions = new XmlDocument(); xmlConditions.Load(string.Format("http://www.google.com/ig/api?weather={0}", location)); if (xmlConditions.SelectSingleNode("xml_api_reply/weather/problem_cause") != null) { conditions = null; } else { conditions.City = xmlConditions.SelectSingleNode("/xml_api_reply/weather/forecast_information/city").Attributes["data"].InnerText; conditions.Condition = xmlConditions.SelectSingleNode("/xml_api_reply/weather/current_conditions/condition").Attributes["data"].InnerText; conditions.TempC = xmlConditions.SelectSingleNode("/xml_api_reply/weather/current_conditions/temp_c").Attributes["data"].InnerText; conditions.TempF = xmlConditions.SelectSingleNode("/xml_api_reply/weather/current_conditions/temp_f").Attributes["data"].InnerText; conditions.Humidity = xmlConditions.SelectSingleNode("/xml_api_reply/weather/current_conditions/humidity").Attributes["data"].InnerText; conditions.Wind = xmlConditions.SelectSingleNode("/xml_api_reply/weather/current_conditions/wind_condition").Attributes["data"].InnerText; } return conditions; }
As you see, it uses an instance of the Conditions class to store the actual values and then returns the instance with the values in it. A bit confusing is the following line:
if (xmlConditions.SelectSingleNode("xml_api_reply/weather/problem_cause") != null)
It checks whether the XML response contains a problem_cause node. The presence of this node in the response means that the API call failed for some reason (most likely, a incorrect location was used).
The bad XML response looks like this:
<?xml version="1.0" ?> <xml_api_reply version="1"> <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0"> <problem_cause data="Information is temporarily unavailable." /> </weather> </xml_api_reply>
Now, let's add a function (also to the Weather class) that will get the forecast for the specified location. Once again, it is using the Conditions class, but this time it returns a List of Conditions (therefore, multiple instances of the Conditions class, since it is a four-day forecast).
/// <summary> /// The function that gets the forecast for the next four days. /// </summary> /// <param name="location">City or ZIP code</param> /// <returns></returns> public static List<Conditions> GetForecast(string location) { List<Conditions> conditions = new List<Conditions>(); XmlDocument xmlConditions = new XmlDocument(); xmlConditions.Load(string.Format("http://www.google.com/ig/api?weather={0}", location)); if (xmlConditions.SelectSingleNode("xml_api_reply/weather/problem_cause") != null) { conditions = null; } else { foreach (XmlNode node in xmlConditions.SelectNodes("/xml_api_reply/weather/forecast_conditions")) { Conditions condition = new Conditions(); condition.City = xmlConditions.SelectSingleNode("/xml_api_reply/weather/forecast_information/city").Attributes["data"].InnerText; condition.Condition = node.SelectSingleNode("condition").Attributes["data"].InnerText; condition.High = node.SelectSingleNode("high").Attributes["data"].InnerText; condition.Low = node.SelectSingleNode("low").Attributes["data"].InnerText; condition.DayOfWeek = node.SelectSingleNode("day_of_week").Attributes["data"].InnerText; conditions.Add(condition); } } return conditions; }
Pretty much the same as the function that gets the current conditions, but this one also loops through every forecast_conditions node in the XML document.
The most complicated part of the project is done. Now let's work on the frontend. Switch to the Program.cs file. All you need now is to get the user input and display the conditions for the location specified.
Here is how I organized this process:
static void Main(string[] args) { // The string representing the general input. string input; // The string that will represent the entered command. // Will be a substring of input. string command = string.Empty; Console.WriteLine("cc <Location> - Current conditions"); Console.WriteLine("fc <Location> - Forecast conditions"); Console.WriteLine("ex - Exit"); // The ex command will automatically exit the application. while (command.ToUpper() != "EX") { // Read the command. Console.Write(">"); input = Console.ReadLine(); command = input.Substring(0, 2); switch (command.ToUpper()) { case "CC": { Conditions conditions = new Conditions(); conditions = Weather.GetCurrentConditions(input.Substring(2, input.Length - 2)); if (conditions != null) { Console.WriteLine("Conditions: " + conditions.Condition); Console.WriteLine("Temperature (F): " + conditions.TempF); Console.WriteLine("Temperature (C): " + conditions.TempC); Console.WriteLine("Humidity: " + conditions.Humidity); Console.WriteLine("Wind: " + conditions.Wind); Console.WriteLine(); } else { Console.WriteLine("There was an error processing the request."); Console.WriteLine("Please, make sure you are using the correct location or try again later."); Console.WriteLine(); } break; } case "FC": { List<Conditions> conditions = new List<Conditions>(); conditions = Weather.GetForecast(input.Substring(2, input.Length - 2)); if (conditions != null) { foreach (Conditions c in conditions) { Console.WriteLine("Day: " + c.DayOfWeek); Console.WriteLine("Conditions: " + c.Condition); Console.WriteLine("Temperature (High): " + c.High); Console.WriteLine("Temperature (Low): " + c.Low); Console.WriteLine(); } } else { Console.WriteLine("There was an error processing the request."); Console.WriteLine("Please, make sure you are using the correct location or try again later."); Console.WriteLine(); } break; } case "EX": { Console.WriteLine("Application closing..."); break; } default: { Console.WriteLine("Unknown command."); break; } } } // Exit the application with exit code 0 (no errors). Environment.Exit(0); }
This is the Main() method for the application. As you see, it checks the entered command (I tried to keep it simple - just 2 letters for a command for now), and if it is either cc or fc, it shows the conditions (current or forecast).

The input is not case sensitive (in the code, the entered commands are checked against their uppercase equivalents), so CC will act the same way as cc or cC.
Wasn't that complicated after all.
The sample project is attached to this tutorial, so if you are interested to take a look directly at my source code, you are more than welcome to download the ZIP file.
Attached File(s)
-
gwapi_sample.zip (32.57K)
Number of downloads: 16911