[JAVA] OpenWeather API 사용 방법

OpenWeather API

200,000 개가 넘는 도시를 포함하여 지구상의 모든 위치에 대한 현재 날씨 데이터에 액세스 할 수 있습니다. 현재 날씨는 글로벌 모델과 4만 개가 넘는 기상 관측소의 데이터를 기반으로 자주 업데이트됩니다. 데이터는 JSON, XML 또는 HTML 형식으로 제공됩니다.
출처 : OpenWeather

OpenWeather API를 사용하여 현재 날씨 데이터를 조회하였다.

현재 날씨 데이터 조회

  • OpenWeather 사이트에 접속해서 API Key를 발급받는다.
  • 메인에서 Current Weather Data를 선택받는다.
  • 조회 조건 및 결과 정보와 다른 기능들에 대해 잘 설명되어 있다.
  • 우리나라 전체에 대한 날씨 데이터를 조회할 것이기 때문에 조회 조건은 다음과 같다.
1
http://api.openweathermap.org/data/2.5/weather?q=Koesan&appid={발급받은 API Key}&lang=kr&units=metric

결과 데이터(JSON 형식)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
"coord": {
"lon": 127.79,
"lat": 36.81
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "튼구름",
"icon": "04d"
}
],
"base": "stations",
"main": {
"temp": 28,
"feels_like": 32.65,
"temp_min": 28,
"temp_max": 28,
"pressure": 1014,
"humidity": 78
},
"visibility": 10000,
"wind": {
"speed": 1.5,
"deg": 270
},
"clouds": {
"all": 75
},
"dt": 1596171614,
"sys": {
"type": 1,
"id": 8131,
"country": "KR",
"sunrise": 1596141211,
"sunset": 1596191806
},
"timezone": 32400,
"id": 1842800,
"name": "Koesan",
"cod": 200
}

1) Respone Domain 생성

기본적으로 결과가 JSON 형식이므로 그에 맞게 도메인을 생성하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.Data;

/**
* OpenWeath API - 현재 날씨 데이터
* @author hgko
*/
@Data
public class OpenWeather {

private List<Weather> weather;

/** 내부 매개 변수 */
private String base;

private Main main;

private Wind wind;

private Clouds clouds;

private Rain rain;

private Snow snow;

/** 가시성 */
private int visibility;

/** 데이터 계산 시간, 유닉스, UTC */
private long dt;

/** UTC에서 초 단위로 이동 */
private int timezone;

/** 도시 ID */
private long id;

/** 도시 이름 */
private String name;

/** 내부 매개 변수 */
private int cod;

@Data
public static class Weather {

/** 기상 조건 ID */
private int id;

/** 날씨 매개 변수 그룹 (비, 눈, 극한 등) */
private String main;

/** 그룹 내 날씨 조건 */
private String description;

/** 날씨 아이콘 ID */
private String icon;
}

@Data
public static class Main {

/** 온도. 단위 기본값 : 켈빈, 미터법 : 섭씨, 임페리얼 : 화씨 */
private float temp;

/** 온도. 단위 기본값 : 켈빈, 미터법 : 섭씨, 임페리얼 : 화씨 */
private float feels_like;

/** 현재 최저 온도.(대규모 대도시 및 도시 지역 내) */
private float temp_min;

/** 현재 최대 온도.(대규모 대도시 및 도시 지역 내)*/
private float temp_max;

/** 대기압 (해수면, 해수면 또는 grnd_level 데이터가 없는 경우), hPa */
private int pressure;

/** 습도, % */
private float humidity;

/** 해수면의 대기압, hPa */
private float sea_level;

/** 지면에서의 대기압, hPa */
private float grnd_level;
}

@Data
public static class Wind {

/** 바람의 속도. 단위 기본값 : meter/sec, 미터법 : meter/sec, 임페리얼 : miles/hour */
private float speed;

/** 풍향,도 (기상) */
private int deg;

/** 바람 돌풍. 단위 기본값 : meter/sec, 미터법 : meter/sec, 임페리얼 : miles/hour */
private float gust;
}

@Data
public static class Clouds {

/** 흐림, % */
private int all;
}

@Data
public static class Rain {

/** 지난 1 시간 동안의 강우량, mm */
@JsonProperty("1h")
private float rain1h;

/** 지난 3 시간 동안의 강우량, mm */
@JsonProperty("3h")
private float rain3h;
}

@Data
public static class Snow {

/** 지난 1 시간 동안의 눈량, mm */
@JsonProperty("1h")
private float snow1h;

/** 지난 3 시간 동안의 눈량, mm */
@JsonProperty("3h")
private float snow3h;
}

@Data
public static class Sys {

private int type;

private int id;

/** 국가 코드 (GB, JP 등) */
private String country;

/** 일출 시간, 유닉스, UTC */
private long sunrise;

/** 일몰 시간, 유닉스, UTC */
private long sunset;
}
}

2) 데이터 조회

SpringFramework에서 지원하는 RestTemplate를 사용하여 조회하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private final String BASE_URL = "http://api.openweathermap.org/data/2.5/weather";
private final String apiKey = ""; // 발급받은 API key

public void getWeatherData() {
StringBuilder urlBuilder = new StringBuilder(BASE_URL);
try {
urlBuilder.append("?" + URLEncoder.encode("q", "UTF-8") + "=Koesan");
urlBuilder.append("&" + URLEncoder.encode("appid", "UTF-8") + "=" + apiKey);
urlBuilder.append("&" + URLEncoder.encode("lang", "UTF-8") + "=kr");
urlBuilder.append("&" + URLEncoder.encode("units", "UTF-8") + "=metric");

RestTemplate restTemplate = new RestTemplate();
OpenWeather response = restTemplate.getForObject(urlBuilder.toString(), OpenWeather.class);

System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}

3) 결과 확인

정상적으로 결과가 출력되었는지 확인하고 정상이면 날씨 데이터들을 가공해서 사용하도록 한다.

추가 내용

풍향 데이터 변환

날씨 API에서 풍향 데이터는 대부분이 degree(integer) 형식으로 되어 있기 때문에 방향을 나타내는 String 형식으로 나타낼 필요가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Enum 정의
@Getter
public enum WindType {
N0(0, "북"),
NNE(1, "북북동"),
NE(2, "북동"),
ENE(3, "동북동"),
E(4, "동"),
ESE(5, "동남동"),
SE(6, "남동"),
SSE(7, "남남동"),
S(8, "남"),
SSW(9, "남남서"),
SW(10, "남서"),
WSW(11, "서남서"),
W(12, "서"),
WNW(13, "서북서"),
NW(14, "북서"),
NNW(15, "북북서"),
N16(16, "북");

private int code;

private String name;

private WindType(int code, String name) {
this.code = code;
this.name = name;
}

public static WindType value(int value) {
for (WindType type : WindType.values()) {
if (type.getCode() == value) {
return type;
}
}
return null;
}
}

Enum을 사용하여 편리하게 변환한다.

1
2
3
4
5
private String getWindDirection(int degree) {
int result = (int)((degree + 22.5 * 0.5) / 22.5);
WindType windType = WindType.value(result);
return windType.getName();
}
1
2
3
4
public static void main(String[] args) {
String wd = getWindDirection(270);
System.out.println("풍향 : " : wd);
}

결과

1
풍향 : 서

날씨 정보 변환

Share