반응형


상당히 오랫만에 블로그에 글을 올리는 듯 합니다.

진행중인 프로젝트이며, 이것 저것 벌려놓은 것이 많다보니..

아무래도 블로그에 소홀하게 될 수 밖에 없는 것 같습니다.

 

어제 문뜩 데브피아에 답변달기 놀이를 하기 위해서 들어갔는데..

이런 질문이 있더군요.. "날씨 정보를 받아보고 싶어요."

그래서 잘 정리된 블로그가 있길래 링크를 달아주었습니다.

이곳에는 ASP.NET으로 되어 있었지만..

제 딴에는.. '어차피 Winform이건 ASP.NET이건 XML로 받아와서 파싱해서 사용하는건 같다.'

라고 생각했는데.. 저만의 오산이었나 봅니다.

대부분 이런 기능을 검색하면 ASP.NET으로 되어 있는 예제들이 수두룩 하지요.

 

혹시나 위와 같은신 분들이 계실까봐.. WinForm으로 포스팅을 해봅니다.

 

 

 

# 본 글에서 사용되는 WeatherReader클래스는 데브피아의 조동현님의 글에서 발췌하였습니다.

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=217&MAEULNO=8&no=28438&page=2

 

 

 

 환경
 

 - Visual Studio 2008

 - .Net Framework 3.0 이상

 - WinForm with C#

 - Google API

 

 

 

 

구글에서는 날씨정보를 받아 볼 수 있는 OpenAPI를 별도로 제공해 주고 있습니다.

다음 쿼리스트링을 이용하면 날씨 정보가 담긴 XML문서를 받아볼 수 있지요.

 

http://www.google.co.kr/ig.api?weather=도시 또는 지역명

 

 서울에 대해서 받아본 XML

 

 

보이는 것처럼 이미지를 비롯한..

당일의 날씨 정보 및 해당 주(week)의 날씨에 대한 정보를 제공 받을 수 있습니다.

 

헌데.. 일부 사람들은.. Google은 크로스 도메인을 지원하지 않아서 안된다는 등..

이런 저런 이야기가 많더군요.

 

설마 그럴리가 있나요. ^^

 

그. 래. 서. 간단하게 제작해보았습니다. 현재 소스는 오늘의 날씨 정보만을 받아오는데요.

XML파싱하는 부분을 조금만 편집하면 어렵지 않게.. 주(Week) 단위의 정보도 받아올 수 있겠지요 :)

 

우선 저는 2개의 클래스를 사용했습니다.

 

하나는 예상하시는 것 처럼.. 날씨 정보를 받아와서 파싱하는 것 까지 진행해주는 클래스이며..

다른 한 클래스는 파싱된 정보를 저장할 수 있는 클래스입니다.

 

 

 WeatherReader 클래스

 구글 API를 이용하여 날씨 정보를 가져오고, 받아온 XML데이터를 파싱하는 클래스

 

 주요 메서드 : WeatherData Reading(string strCity);

                    매개변수로 지역명(영문)을 받으며,

                    해당 지역에 대해서 종합된 날씨 정보인 WeatherData의 객체를 리턴함.

 

     class WeatherReader
    {
        private string headerURL = @"http://www.google.co.kr/";

        public WeatherReader()
        {
        }

        public WeatherData Reading(string strCity)
        {
            try
            {
                WebClient wc = new WebClient();
                string buffer = wc.DownloadString(string.Format("{0}ig/api?weather={1}%20", headerURL, strCity));
                wc.Dispose();

                StringReader sr = new StringReader(buffer);
                XmlDocument doc = new XmlDocument();
                doc.Load(sr);
                sr.Close();

                XmlNode currentNode = doc.SelectSingleNode("xml_api_reply/weather/current_conditions");
                if (currentNode == null)
                    return null;

                string condition = GetNodeValue(currentNode, "condition");
                string temp_f = GetNodeValue(currentNode, "temp_f");     //화씨
                string temp_c = GetNodeValue(currentNode, "temp_c");   //섭씨
                string humidity = GetNodeValue(currentNode, "humidity");

                string wind_condition = GetNodeValue(currentNode, "wind_condition");
                humidity = humidity.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[1];

                return new WeatherData(LoadIcon(GetNodeValue(currentNode, "icon")), strCity, condition,

                                                   wind_condition, temp_c, humidity);
            }
            catch (Exception)
            {
                return null;
            }
        }

        private Bitmap LoadIcon(string url)
        {
            try
            {
                if (string.IsNullOrEmpty(url))
                    return null;

                WebClient wc = new WebClient();
                url = headerURL + url;
                Byte[] buffer = wc.DownloadData(url);
                wc.Dispose();
                MemoryStream ms = new MemoryStream(buffer);
                Bitmap bmp = new Bitmap(ms);
                ms.Dispose();
                return bmp;
            }
            catch
            {
                return null;
            }
        }

        private string GetNodeValue(XmlNode parent, string name)
        {
            try
            {
                XmlAttribute attr = parent.SelectSingleNode(name).Attributes["data"];
                if (attr != null)
                    return attr.Value;
                return null;
            }
            catch
            {
                return null;
            }
        }
    }

 

 

 

아래는 위에서 사용된 WeatherData클래스 입니다.

단순히 파싱된 날씨 정보를 저장하기 위한 클래스이죠..

 

 

 WeatherData 클래스

 - 그다지 분석할 필요성은 없음.

 - ToString을 사용하면 문자열로 표현된 해당 지역의 날씨 정보가 등장.

 

     class WeatherData
    {

        public Bitmap Icon { get; private set; }
        public string City { get; private set; }
        public string Condition { get; private set; }
        public string WindCondition { get; private set; }
        public string Temperature { get; private set; }
        public string Humidity { get; private set; }

        public WeatherData(Bitmap icon, string city, string condition, string wind, string temperature, string humidity)
        {
            Icon = icon;
            City = city;
            Condition = condition;
            WindCondition = wind;
            Temperature = temperature;
            Humidity = humidity;
        }

        public override string ToString()
        {
            return  City + " 날씨 정보..\r\n" + Condition + "\r\n" + WindCondition

                            + "\r\n온도:" + Temperature + ", 습도:" + Humidity;
        }
    }

 

 

 

아래는 위 클래스를 기반으로 직접 실행시켜본  것입니다.

 

 

 

 

예제 소스는 파일로 별첨합니다.

모두 유익한 개발되시길....

 

반응형

+ Recent posts