옥답 OpenApi.. OpenApi는 알겠는데..옥답이라는건 처음 들어보시죠? 옥답은 농업정보서비스를 제공해주는 사이트입니다. 이 오픈API를 쓴 이유는 이번 선문비트 고급과정 마지막 프로젝트에서 주제가 "작물정보제공서비스"였기 때문에 옥답에서 OpenApi를 썼습니다. 다른 OpenApi와 별반 다름없이 Xml로 되어있어 끌어다 쓰면 됩니다. 자세한 설명은 지금부터~ 그리고~지금 부터 허접한 소스 공개 고고씽~ (반말인점 감안해주세요 ㅋㅋ 문서화한거라서리~) |
옥답 OpenAPI는 다양한 농업정보서비스(가격/유통, 우리농뉴스 등)를 사용자의 웹 환경에서 활용할 수 있도록 외 부에 공개한 개발자 인터페이스이다.
옥답 OpenAPI를 이용하여 옥답의 기술과 서비스를 활용할 수 있으며, 옥답 OpenAPI는 옥답 의 다양한 서비스를 웹 페이지에서 활용할 수 있도록 지원 할 뿐만 아니라, 더 나아가 여러 가지 서비스를 혼합한 창의적인 애플리케이션을 스스로 제작할 수 있도록 지원한다.
예를 들어, 옥답뉴스 API를 이용하면 전국에서 제공되는 농업/농촌의 생생한 뉴스정보를 제공 받을 수 있을 뿐만 아니라, 오픈백과 및 용어 사전 API와 결합해서 농업정보의 전문지식까지 활 용할 수 있다. 이러한 것을 서비스간 융합(mashup)이라고 하며, 이러한 융합을 통해 새로운 가치 를 창출해 낼 수 있다. 더불어 옥답은 OpenAPI 활용 방법을 상세하게 안내하기 때문에, 작은 노 력으로도 여느 정보보다 나은 농업정보를 활용할 수 있다.
<옥답에서 사용한 가격유통 사용의 예>
<옥답에서 사용한 내 고장 소식의 예>
먼저, 가격정보 OpenApi를 해보겠다.
옥답 사이트에서는 웹을 이용해 사용하였지만, 본 프로젝트에서는 WPF를 이용하여, 실시간 가격유통, 내 고장 소식을 구현하였다.
<FarmerBuddy에서 적용시킨 실행화면>
l 각각의 항목들을 담아주는 ArrayList와 변수, 그리고 RealStat의 개체를 생성하고, 전역에 선언해주었다.
ArrayList Bigcode = new ArrayList(); //대코드를 담아주는 ArryaList ArrayList MiddleCode = new ArrayList(); //중코드를 담아주는 ArryaList ArrayList SmallCode = new ArrayList(); //소코드를 담아주는 ArryaList ArrayList MarketCode = new ArrayList(); //시장를 담아주는 ArryaList ArrayList ClassCode = new ArrayList(); //등급를 담아주는 ArryaList int BigNum; //대분류의 콤보박스 인덱스를 담는 변수 int MiddleNum; //중분류의 콤보박스 인덱스를 담는 변수 int SmallNum; //소분류의 콤보박스 인덱스를 담는 변수 int MarketNum; //시장의 콤보박스 인덱스를 담는 변수 int ClassNum; //등급의 콤보박스 인덱스를 담는 변수 RealStat rs = new RealStat(); //ListView의 항목과 각각의 속성들을 현 상황에 맞게 담아주는 개체 생성 |
l 시작버튼을 눌렀을 시, 그리고 프로그램이 실행될 시, 날짜를 받아 대분류로 코드번호를 넘겨준다.
l 그리고, OpenApi는 대게 XML로 되어있다. 그래서 파싱을 해주어야 되는데, XmlDocument를 이용하여, Load를 시켜주고, 각각의 항목마다 XmlNode를 선언해주고, 읽어들이면 된다. (이 부분은 계속적으로 반복된다)
private void OK() //대분류의 코드를 얻기 위한 함수 { if (!(startday.Text == string.Empty || endday.Text == string.Empty)) //시작일, 기준일에 Empty string이 없을경우 { BigCombo.Items.Clear(); //대분류 콤보박스 Clear Bigcode.Clear(); //대분류ArrayList Clear XmlDocument doc = new XmlDocument(); //XmlDocument 생성 doc.Load(String.Format("http://openapi.affis.net/price/realtime/pricexml_class_action.jsp?key=c83ca4580ed2eb6989a520412d63145a&date={0}" + "&lcode=&mcode=&scode=", startday.Text)); // 요청URL(시작일 삽입)을 Load시킴 String code = null; //code 번호를 담는 String변수 String name = null; //name을 담는 String 변수 int index; //Reuslt Node의 Count를 담는 변수 /// 여기서부터 각각의 XmlNode를 읽어들임 XmlNode currentNode = doc.SelectSingleNode("price"); //최상위 price Node 선언 XmlNode result; //result Node 선언 index = currentNode.SelectNodes("result").Count; //result Count수를 index에 대입 for (int i = 0; i < index; i++) //result의 index만큼 반복 { result = currentNode.SelectNodes("result")[i]; //result Node 선언 code = result.SelectSingleNode("code").InnerText; // code Node 선언 후 code 변수에 대입 Bigcode.Add(code); // 대분류 ArrayList에 code 번호를 대입시킴 name = result.SelectSingleNode("name").InnerText; // name Node 선언 후 name String 변수에 대입 BigCombo.Items.Add(name); //대분류 ComboBox에 name을 추가 } BigCombo.SelectedIndex = 0; //대분류 comboBox의 기본값을 인덱스 0으로 초기화 시켜줌 } else //시작일, 기준일에 Empty string이 있을 경우 { MessageBox.Show("날짜를 입력해주세요."); } } |
l 대분류 ComboBox에서 SelectedChanged 이벤트가 일어날 때.
private void Bigcombo_SelectionChanged(object sender, SelectionChangedEventArgs e) //대분류에서 중분류에 필요한 요청 변수를 넘겨줌 { ComboBox currentComboBox = sender as ComboBox; //ComboBox 생성 if (currentComboBox != null) //현재 comboBox의 값이 null이 아닐 경우 { BigNum = currentComboBox.SelectedIndex; //현재 comboBox의 인덱스를 BigNum에 대입 if (BigNum == -1) //BigNum의 index가 -1 인 경우 { MiddleComBo.Items.Clear(); //중분류 comboBox를 클리어 return; } } MiddleComBo.Items.Clear(); //중분류 comboBox 클리어 MiddleCode.Clear(); //중분류 XmlDocument doc = new XmlDocument(); //XmlDocument 생성 doc.Load(String.Format("http://openapi.affis.net/price/realtime/pricexml_class_action.jsp?key=c83ca4580ed2eb6989a520412d63145a&date={0}" + "&lcode={1}&mcode=&scode=", startday.Text, Bigcode[BigNum])); // 요청URL(시작일, 대분류code 삽입)을 Load시킴 String code = null; //code 번호를 담는 String변수 String name = null; //name을 담는 String 변수 int index; //Reuslt Node의 Count를 담는 변수 /// 여기서부터 각각의 XmlNode를 읽어들임 XmlNode currentNode = doc.SelectSingleNode("price"); index = currentNode.SelectNodes("result").Count; XmlNode result; for (int i = 0; i < index; i++) { result = currentNode.SelectNodes("result")[i]; code = result.SelectSingleNode("code").InnerText; MiddleCode.Add(code); // 중분류 ArrayList에 code 번호를 대입시킴 name = result.SelectSingleNode("name").InnerText; MiddleComBo.Items.Add(name); //중분류 comboBox에 name 추가 } MiddleComBo.SelectedIndex = 0; //중분류 comboBox의 기본값을 인덱스 0으로 초기화 시켜줌 } |
l 중분류 ComboBox에서 SelectedChanged 이벤트가 일어날 때,
l 소분류, 시장,등급 항목들도 방법은 똑같다. (요청변수 주의)
private void MiddleComBo_SelectionChanged(object sender, SelectionChangedEventArgs e) //중분류에서 소분류에 필요한 요청 변수를 넘겨줌 { ComboBox currentComboBox = sender as ComboBox; if (currentComboBox != null) { MiddleNum = currentComboBox.SelectedIndex; //중분류 comboBox의 인덱스를 MiddleNum으로 대입 if (MiddleNum == -1) //MiddleNum이 -1인 경우 { SmallCombo.Items.Clear(); //소분류 comboBox 클리어 return; } } SmallCombo.Items.Clear(); //소분류 comboBox 클리어 SmallCode.Clear(); //소분류 ArrayList 클리어 XmlDocument doc = new XmlDocument(); doc.Load(String.Format("http://openapi.affis.net/price/realtime/pricexml_class_action.jsp?key=c83ca4580ed2eb6989a520412d63145a&date={0}" + "&lcode={1}&mcode={2}&scode=", startday.Text, Bigcode[BigNum], MiddleCode[MiddleNum])); // 요청URL(시작일, 대분류code, 중분류 code 삽입)을 Load시킴 String code = null; String name = null; int index; XmlNode currentNode = doc.SelectSingleNode("price"); index = currentNode.SelectNodes("result").Count; XmlNode result; for (int i = 0; i < index; i++) { result = currentNode.SelectNodes("result")[i]; code = result.SelectSingleNode("code").InnerText; SmallCode.Add(code); // 소분류 ArrayList에 code 번호를 대입시킴 name = result.SelectSingleNode("name").InnerText; SmallCombo.Items.Add(name); // 소분류 comboBox에 name 추가 } SmallCombo.SelectedIndex = 0; //소분류 comboBox의 기본값을 인덱스 0으로 초기화 시켜줌 |
l 결과 화면을 보여줄 때 이다.
private void ClassCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) //등급에서 결과에 필요한 요청 변수를 넘겨줌 { ComboBox currentComboBox = sender as ComboBox; if (currentComboBox != null) { ClassNum = currentComboBox.SelectedIndex; //등급 comboBox의 인덱스를 ClassNum으로 대입 if (ClassNum == -1) //ClassNum이 -1인 경우 { rs.Clear(); //RealStat 개체 클리어 return; } } rs.Clear();//RealStat 개체 클리어 XmlDocument doc = new XmlDocument(); doc.Load(String.Format("http://openapi.affis.net/price/realtime/pricexml_search.jsp?key=c83ca4580ed2eb6989a520412d63145a&sdate={0}&edate={1}" + "&ccode={2}&lcode={3}&mcode={4}&scode={5}&gcode={6}&snum=&enum=" , startday.Text, endday.Text, MarketCode[MarketNum], Bigcode[BigNum], MiddleCode[MiddleNum], SmallCode[SmallNum], ClassCode[ClassNum])); // 요청URL(시작일,기준일.시장번호, 대분류code, 중분류 code,소분류 code,등급 code 삽입)을 Load시킴 XmlNode currentNode = doc.SelectSingleNode("price"); int index = currentNode.SelectNodes("result").Count; //count 돌리기 //날짜, 도매법인,품목,품종,규격,등급,평균가,최저가,최고가,거래량을 담을 변수선언 String dates, coname, mclassname, sclassname, unitname, gradename, avgprice, maxprice, minprice, sumamt; XmlNode result; for (int i = 0; i < index; i++) { /// 각각의 Node들을 해당하는 변수에 대입 result = currentNode.SelectNodes("result")[i]; dates = result.SelectSingleNode("dates").InnerText; coname = result.SelectSingleNode("coname").InnerText; mclassname = result.SelectSingleNode("mclassname").InnerText; sclassname = result.SelectSingleNode("sclassname").InnerText; unitname = result.SelectSingleNode("unitname").InnerText; gradename = result.SelectSingleNode("gradename").InnerText; avgprice = result.SelectSingleNode("avgprice").InnerText; maxprice = result.SelectSingleNode("maxprice").InnerText; minprice = result.SelectSingleNode("minprice").InnerText; sumamt = result.SelectSingleNode("sumamt").InnerText; //RealStat 개체에 추가 rs.Add(new RealTime(dates, coname, mclassname, sclassname, unitname, gradename, avgprice + "원", maxprice + "원", minprice + "원", sumamt)); price_list.ItemsSource = rs; //ListView에 항목들 바인딩 } |
l ListView Xaml 부분
<ListView Margin="37,176,0,0" Name="price_list" BorderThickness="1" Grid.IsSharedSizeScope="True"ItemsSource="{Binding Source={StaticResource totalview}}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Left" Width="875" Height="265" VerticalAlignment="Top" FontFamily="맑은고딕"> <ListView.View> <GridView AllowsColumnReorder="True"ColumnHeaderToolTip="Total"> <GridViewColumn DisplayMemberBinding="{Binding Path=Date}" Header="날짜" Width="70"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Domae}" Header="도매법인" Width="80"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Pummok}" Header="품목" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Pumjong}" Header="품종" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Size}" Header="규격" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Rate}" Header="등급" Width="100"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Avg}" Header="평균가" Width="80"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Minmoney}" Header="최저가" Width="80"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Maxmoney}" Header="최고가" Width="80"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Gurae}" Header="거래량" Width="80"/> </GridView> </ListView.View> |
l ListView에 채워주는 RealTime 클래스 소스 부분
public class RealTime : INotifyPropertyChanged { public string date; //날짜 public string domae; //도매법인 public string pummok; //품목 public string pumjong; //품종 public string size; //규격 public string rate; //등급 public string avg; //평균가 public string minmoney; //최소가 public string maxmoney; //최대가 public string gurae; //거래량 /// <summary> /// 위에 있는 변수들을 각각 get,set 속성으로... /// </summary> public RealTime() { } public RealTime(string _date, string _domae, string _pummok, string _pumjong, string _size, string _rate, string _avg, string _minmoney, string _maxmoney, string _gurae) //생성자 { date = _date; domae = _domae; pummok = _pummok; pumjong = _pumjong; size = _size; rate = _rate; avg = _avg; minmoney = _minmoney; maxmoney = _maxmoney; gurae = _gurae; } public string Date { set { date = value; OnPropertyChanged("Date"); } get { return date; } } //이런 식으로, 각각의 항목들을 OnPropertyChanged 인터페이스를 사용하고, 속성을 정해준다. //(생략) private void OnPropertyChanged(string p) //데이터를 바인딩 하기 위한 인터페이스 { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(p)); } } #region INotifyPropertyChanged 멤버 public event PropertyChangedEventHandler PropertyChanged; #endregion } public class RealStat : ObservableCollection<RealTime> { public RealStat() { } public void AddRealStat(RealTime r) { Add(r); //추가 함수 } |
l 달력 컨트롤에 대한 소스 부분
public partial class Calendar : Window { public string myday = string.Empty; // 년,월,일 을 담을 string 변수 선언 public Calendar() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { WinCalendarDll.Calendar c = new WinCalendarDll.Calendar(); //WinForm에서 가져온 달력컨트롤을 생성 windowsFormsHost1.Child = c; c.Mytoday += new WinCalendarDll.Calendar.GetToday(c_Mytoday); //년,월,일을 가져오는 이벤트를 발생 } void c_Mytoday(string day) { string year = DateTime.Today.Year.ToString(); //현재 년도 string month = DateTime.Today.Month.ToString(); //현재 월 if (month.Length == 1) { month = "0" + month; } int Nowday = DateTime.Today.Day; //현재 일 string days = string.Empty; if (Nowday < 10) //10일 미만일 경우 { days = "0" + Nowday; //앞에 0을 붙여줌 string today = year + month + days; if (int.Parse(today) >= int.Parse(day)) //현재 날짜보다 작을 경우 { myday = day; Close(); } else //현재 날짜보다 클 경우 { MessageBox.Show("이전 데이터만 볼 수 있습니다"); return; } } else { string today = year + month + Nowday; if (int.Parse(today) >= int.Parse(day)) //현재 날짜보다 작을 경우 { myday = day; Close(); } else //현재 날짜보다 클 경우 { MessageBox.Show("이전 데이터만 볼 수 있습니다"); return; } } } |
l 달력보기 버튼을 눌렀을 시
private void button1_Click(object sender, RoutedEventArgs e) //달력보기 { Calendar cal = new Calendar(); //달력 개체를 생성 cal.ShowDialog(); //달력을 보여줌 endday.Text = cal.myday; //달력에서 클릭한 년,월,일을 대입함 |
l 첫 화면에 기준일을 현재일자로 초기값을 넣어주는 함수이다.
Ex) 20100819 이런식으로 들어가야 하기 때문에 0을 붙여준다.
private void standardTime() //기준일 { string year = DateTime.Today.Year.ToString(); //현재 년도 가져옴 string month = DateTime.Today.Month.ToString(); //현재 월 가져옴 if (month.Length == 1) //현재 월이 1~9월일때 { month = "0" + month; //앞에 0을 붙여줌 [ex) 08] } int day = DateTime.Today.Day; //현재 일 가져옴 string days = string.Empty; if (day < 10) //현재 일이 1~9일 경우 { days = "0" + day; //앞에 0을 붙여줌 [ex)08] string today = year + month + days; // 최종으로 현재 년,월,일을 대입함 endday.Text = today; //기준일 TextBox에 대입 } else //현재일이 10일 이상일 경우 { string today = year + month + day; // 최종으로 현재 년,월,일을 대입함 endday.Text = today; //기준일 TextBox에 대입 } |
l 시작일을 초기값을 넣어주는 함수
private void StartTime() //시작일 { int year = DateTime.Now.Year; // 현재 년도 가져옴 int month = DateTime.Now.Month; // 현재 월 가져옴 int day = DateTime.Now.Day; // 현재 일 가져옴 int result = 0; string days = string.Empty; if (day == 1) // 1일일 때 { if (month == 1) //1월 일때 { month = 12; // 12월로 초기화 year -= 1; // 1년을 뺀다. } else //1월이 아닐 경우 { month -= 1; } //Day 계산 result = DateTime.DaysInMonth(year, month); result -= 2; day = result; } else if (day == 2) //2일일 경우 { if (month == 1) //1월일 경우 { month = 12; // 12월로 초기화 year -= 1; // 1년을 뺀다. } else //1월이 아닐 때 { month -= 1; } result = DateTime.DaysInMonth(year, month); result -= 1; day = result; } else if (day > 2) { day -= 3; //현지일로부터 3일을 빼줘, 시작일을 현재일로부터 -3일을 해준다. } string MonthResult = string.Empty; if (month < 10) { MonthResult = "0" + month; } if (day < 10) //9일 이하 일때 { days = "0" + day; //앞에 0을 붙여줌 string today = year + MonthResult + days; startday.Text = today; } else //10일 이상일 경우 { string today = year + MonthResult + day; startday.Text = today; } } |
'programming > Open API' 카테고리의 다른 글
[WPF] 구글 날씨 OpenApi (3) | 2011.07.28 |
---|---|
옥답OpenApi 두 번째 (지역 뉴스 정보) (0) | 2010.08.19 |