Laden...

Google Weather API

Erstellt von KainPlan vor 14 Jahren Letzter Beitrag vor 14 Jahren 6.451 Views
K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren
Google Weather API

Beschreibung:

Eine Klasse um Daten aus einer abfrage der Google Weather API zu verarbeiten. Besizt die Möglichkeit die Bilddaten in einem cache zu speichern.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Xml;
using System.Net;

namespace Weather
{
    /// <summary>
    /// Data for the current condition
    /// </summary>
    public class CurrentCondition
    {
        public string Condition { get; set; }
        public string IconLocation { get; set; }
        public Image Icon { get; set; }
        public string Humidity { get; set; }
        public string WindCondition { get; set; }
        public int TempF { get; set; }
        public int TempC { get; set; }

        public object Tag { get; set; }
    }
    /// <summary>
    /// Data for a forecast.
    /// </summary>
    public class ForecastCondition
    {
        public string Condition { get; set; }
        public string DayOfWeek { get; set; }
        public string IconLocation { get; set; }
        public Image Icon { get; set; }
        public int TempHigh { get; set; }
        public int TempLow { get; set; }

        public object Tag { get; set; }
    }
    /// <summary>
    /// Set of weather data.
    /// </summary>
    public class WeatherDataSet
    {
        /// <summary>
        /// The city where you want to request the weather for.
        /// </summary>
        public string City { get; set; }
        /// <summary>
        /// Date of request.
        /// </summary>
        public DateTime Request { get; set; }
        /// <summary>
        /// The current conditions.
        /// </summary>
        public CurrentCondition CurrentCondition { get; set; }
        /// <summary>
        /// The forecast conditions.
        /// </summary>
        public List<ForecastCondition> ForecastConditions { get; set; }
    }
    /// <summary>
    /// For use with google xml api reply version 1.
    /// </summary>
    public class Weather
    {
        #region Constructors
        /// <summary>
        /// Create a new instance to request the weather from google.
        /// </summary>
        /// <param name="city">The city where you want to request the weather for.</param>
        /// <param name="cacheFolder">[Optional string.Empty] The folder where you want to cache the images.</param>
        public Weather(string city, string cacheFolder) 
        {
            WeatherData = new WeatherDataSet();
            WeatherData.Request = DateTime.MinValue;
            WeatherData.CurrentCondition = new CurrentCondition();
            WeatherData.ForecastConditions = new List<ForecastCondition>();

            CacheFolder = cacheFolder;
            RequestUrl = "http://www.google.com/ig/api?weather=";
            Culture = System.Globalization.CultureInfo.CurrentCulture.Name;
            City = city;
        }
        #endregion

        #region Public
        /// <summary>
        /// Set of data where the weatherinformations are stored.
        /// </summary>
        public WeatherDataSet WeatherData { get; set; }
        /// <summary>
        /// [Optional string.Empty] The folder where you want to cache the images.
        /// </summary>
        public string CacheFolder { get; private set; }
        /// <summary>
        /// Culture for witch to get the weather. If the culture is not availible en-us is used.
        /// </summary>
        public string Culture { get; set; }
        /// <summary>
        /// The google weather api url.
        /// </summary>
        public string RequestUrl { get; set; }
        /// <summary>
        /// The city where you want to request the weather for.
        /// </summary>
        public string City { get; set; }
        /// <summary>
        /// Load's the weather syncron.
        /// </summary>
        /// <returns> true if loaded. </returns>
        public bool LoadWeather()
        {
            return _getWeather();
        }
        /// <summary>
        /// Load's the weather syncron.
        /// </summary>
        /// <param name="City"> The city where you want to request the weather for. </param>
        /// <returns> true if loaded. </returns>
        public bool LoadWeather(string City)
        {
            this.City = City;
            return _getWeather();
        }
        #endregion

        #region Privates
        private bool _getWeather()
        {
            string url;
            string cultureHeader;
            HttpWebResponse webResponse;
            Stream webStream;
            StreamReader webStreamReader;
            XmlDocument xmlWeather;
            HttpWebRequest webRequest;
            try
            {
                url = Uri.EscapeUriString(this.RequestUrl + this.City);
                cultureHeader = string.Format("Accept-Language: {0}, en-us", this.Culture);

                webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                webRequest.ReadWriteTimeout = 1000 * 60;
                webRequest.Headers.Add(cultureHeader);

                webResponse = (HttpWebResponse)webRequest.GetResponse();
                webStream = webResponse.GetResponseStream();
                webStreamReader = new StreamReader(webStream, Encoding.Default);

                xmlWeather = new XmlDocument();
                xmlWeather.LoadXml(webStreamReader.ReadToEnd());
            }
            catch { return false; }

            if (!_getCurrentCondition(xmlWeather))
            {
                //TODO: Maybe a new version of google weather api is out...
                return false;
            }
            if (!_getForecasts(xmlWeather))
            {
                //TODO: Maybe a new version of google weather api is out...
                return false;
            }

            WeatherData.Request = DateTime.Now;
            WeatherData.City = this.City;

            return true;
        }
        private bool _getCurrentCondition(XmlDocument doc)
        {
            try
            {
                XmlNode cnode = doc["xml_api_reply"]["weather"]["current_conditions"];
                WeatherData.CurrentCondition.Condition = cnode["condition"].Attributes["data"].Value;
                WeatherData.CurrentCondition.Humidity = cnode["humidity"].Attributes["data"].Value;
                WeatherData.CurrentCondition.TempC = int.Parse(cnode["temp_c"].Attributes["data"].Value);
                WeatherData.CurrentCondition.TempF = int.Parse(cnode["temp_f"].Attributes["data"].Value);
                WeatherData.CurrentCondition.WindCondition = cnode["wind_condition"].Attributes["data"].Value;
                WeatherData.CurrentCondition.IconLocation = cnode["icon"].Attributes["data"].Value;
                WeatherData.CurrentCondition.Icon = _getIcon(WeatherData.CurrentCondition.IconLocation);
            }
            catch { return false; }

            return true;
        }
        private bool _getForecasts(XmlDocument doc)
        {
            try 
            {
                WeatherData.ForecastConditions.Clear();

                XmlNode container = doc["xml_api_reply"]["weather"];
                for (XmlNode cnode = container.FirstChild; cnode != null; cnode = cnode.NextSibling)
                {
                    if (cnode.Name == "forecast_conditions")
                    {
                        ForecastCondition fc = new ForecastCondition();
                        fc.Condition = cnode["condition"].Attributes["data"].Value;
                        fc.DayOfWeek = cnode["day_of_week"].Attributes["data"].Value;
                        fc.TempLow = int.Parse(cnode["low"].Attributes["data"].Value);
                        fc.TempHigh = int.Parse(cnode["high"].Attributes["data"].Value);
                        fc.IconLocation = cnode["icon"].Attributes["data"].Value;
                        fc.Icon = _getIcon(WeatherData.CurrentCondition.IconLocation);

                        WeatherData.ForecastConditions.Add(fc);
                    }
                }
            }
            catch { return false; }

            return true;
        }
        private Image _getIcon(string loc) 
        {
            Image icon = null;
            string path = string.Empty;
            bool loaded = true;
            HttpWebRequest webRequest;
            HttpWebResponse webReponse;
            Stream webStream;

            if (this.CacheFolder != string.Empty)
            {
                path = Path.Combine(this.CacheFolder, Path.GetFileName(loc));
                if (File.Exists(path))
                {
                    try
                    {
                        icon = Image.FromFile(path);
                        loaded = false;
                    }
                    catch { icon = null; }
                }                
            }

            if (icon == null)
            {
                try
                {
                    webRequest = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com" + loc);
                    webReponse = (HttpWebResponse)webRequest.GetResponse();
                    webStream = webReponse.GetResponseStream();
                    icon = Image.FromStream(webStream);
                }
                catch
                {
                    icon = null;
                    loaded = false;
                }
            }

            if (path != string.Empty && icon != null && loaded)
            {
                try
                {
                    icon.Save(path);
                }
                catch { };
            }

            return icon;
        }
        #endregion
    }
}

Schlagwörter: Google, Weather, Wetter, API

H
364 Beiträge seit 2007
vor 14 Jahren

habs nicht getestet, sieht aber auf den ersten blick recht nett aus
wenn ich es richtig interpretiere, müssen die daten für die abfrage imemr erst aus einer xml datei gelesen werden, da wäre eine überladung für direkte abfragen hilfreich

mfG Hobofan

K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren

Hallo Hobofan!

In wie fern meinst du das mit der direktabfrage? Soll das dokument direkt übergeben werden können?

H
364 Beiträge seit 2007
vor 14 Jahren

Tschuldigung, das war unklar ausgedrückt

Ich meine überladungen der funktionen wie z.B der getforecasts funktion bei denen dann statt dem xmldocument , die werte die in dem xmldocument stehen als parameter akzeptiert werden, so dass nicht extra ein xmldocument erzeugt werden muss um die funktion zu benutzen

MfG hobofan

K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren

Hm, ich seh da dann irgendwie nicht denn sinn der Klasse. Wenn man die Werte ja schon hat braucht man die Klasse ja nicht mehr. 🤔