목차 | |
1. | 날씨 아이콘 |
1. 날씨 아이콘
▣ OpenWeather API
OpenWeather API에서 날씨 아이콘을 출력하려면 weather에서 날씨에 따른 아이콘 코드를 가져와야 함
...
"weather": [
{
"id": 500,
"main":"Rain",
"description": "light rain",
"icon": "10n"
}
],
...
icon의 코드는 weather 배열에 있는 첫 번째 객체에 있음
아래의 OpenWeather API URL을 통해서 이미지를 화면에 출력할 수 있음
https://openweathermap.org/img/wn/10d@2x.png
URL을 해석하자면
- https://openweathermap.org/img/wn/: OpenWeatherMap의 아이콘 이미지가 위치하는 기본 URL임
- 10d: 날씨 아이콘의 코드임 (숫자 + 영어 형태)
- 숫자는 날씨 상태를 나타내며, 10은 비가 오는 날씨를 의미함
- 영어는 시간대를 나타내며, d는 낮을 의미함
- @2x: 이미지를 2배 크기로 요청하는 것을 의미함
- .png: 이미지 파일 형식으로 PNG 형식의 아이콘을 요청하는 것을 의미함
=> 따라서, 이 URL은 비가 오고 낮 시간대인 날씨에 해당하는 아이콘을 2배 크기로 요청하는 링크입니다.
◈ 아이콘 목록
url을 활용하여 아이콘을 출력을 다음과 같이 할 수 있음
▶ 코드
◈ index.html
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultrap.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<div layout:fragment="content">
<div class="container-md">
<!-- 카카오맵 API 로딩 (HTTPS 사용)-->
<script type="text/javascript"
th:src="@{'https://dapi.kakao.com/v2/maps/sdk.js?appkey=내 API 키 입력&libraries=services'}"></script>
<p id="status">위치를 찾지 못했습니다</p>
<div id="map" style="width:500px;height:400px;"></div>
<ul id="places"></ul>
<hr>
<form id="addressForm" th:action="@{/}" method="get" style="display: none;">
<input id="addressInput" name="address" type="text" />
</form>
<script th:src="@{/js/currentLocationMap.js}"></script>
<div th:unless="${weather == null}">
<li th:text="'아이콘 : ' + ${weather['weather_icon']}"></li>
<img th:src="'https://openweathermap.org/img/wn/' + ${weather['weather_icon']} + '@2x.png'" alt="Weather Icon" />
<li th:text="'날씨 : ' + ${weather['weather_main']}"></li>
<li th:text="'날씨 설명 : ' + ${weather['weather_description']}"></li>
<li th:text="'온도 : ' + ${weather['temperature']} + '℃'"></li>
<li th:text="'습도 : ' + ${weather['humidity']} + '%'"></li>
</div>
<div th:if="${weather == null}">
<p>날씨 정보를 불러올 수 없습니다.</p>
</div>
</div>
</div>
◈ WeatherService.java
package com.project.joonggo.service;
import org.springframework.beans.factory.annotation.Value;
import org.json.JSONObject;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Service
@PropertySource("classpath:config.properties")
public class WeatherService {
@Value("${Geocoder_API_KEY}")
private String Geocoder_API_KEY;
@Value("${OpenWeatherMap_API_KEY}")
private String OpenWeatherMap_API_KEY;
// 위도와 경도를 Map<String, String> 형태로 반환하는 메서드
public Map<String, String> returnLanLon(String address){
Map<String, String> coordinates = new HashMap<>();
String apiKey = Geocoder_API_KEY; // Geocoder API 2.0에서 발급받은 API Key 작성할 것
try{
// 주소 인코딩 (인코딩 X 시 400 에러 발생함)
String encodedAddress = URLEncoder.encode(address, StandardCharsets.UTF_8.toString());
String apiUrl = "https://api.vworld.kr/req/address?service=address&request=getCoord&key=" + apiKey + "&type=ROAD&address=" + encodedAddress;
// URL 객체 생성
URL url = new URL(apiUrl);
// 연결 설정
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// 응답 코드 확인
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
// 응답 내용 읽기
while ((inputLine = in.readLine()) != null){
response.append(inputLine);
}
in.close();
// JSON 응답 파싱
JSONObject jsonResponse = new JSONObject(response.toString());
if(jsonResponse.getJSONObject("response").getString("status").equals("OK")) {
String x = jsonResponse.getJSONObject("response").getJSONObject("result").getJSONObject("point").getString("x");
String y = jsonResponse.getJSONObject("response").getJSONObject("result").getJSONObject("point").getString("y");
coordinates.put("lat", y);
coordinates.put("lon", x);
}
}else{
System.out.println("Error: " + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
}
return coordinates;
}
// 날씨 정보를 Map<String, String> 형태로 반환하는 메서드
public Map<String, String> returnWeather(Map<String, String> lanLon){
String apiKey = OpenWeatherMap_API_KEY; // Open Weather Map 날씨 API에서 발급받은 API Key 작성할 것
// 넘어온 위도, 경도를 포함한 url
String apiUrl = "https://api.openweathermap.org/data/2.5/weather?lat=" + lanLon.get("lat") + "&lon=" + lanLon.get("lon") + "&appid=" + apiKey;
Map<String, String> weather = new HashMap<>();
try {
// URL 객체 생성
URL url = new URL(apiUrl);
// 연결 설정
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// 응답 코드 확인
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
// 응답 내용 읽기
while((inputLine = in.readLine()) != null){
response.append(inputLine);
}
in.close();
// JSON 응답 파싱
JSONObject jsonResponse = new JSONObject(response.toString());
weather.put("weather_icon", jsonResponse.getJSONArray("weather").getJSONObject(0).getString("icon"));
weather.put("weather_main", jsonResponse.getJSONArray("weather").getJSONObject(0).getString("main"));
weather.put("weather_description", jsonResponse.getJSONArray("weather").getJSONObject(0).getString("description"));
BigDecimal temp = jsonResponse.getJSONObject("main").getBigDecimal("temp");
BigDecimal tempCelsius = BigDecimal.valueOf(temp.doubleValue() - 273.15).setScale(2, RoundingMode.HALF_UP); // 소수점 둘째 자리에서 반올림
weather.put("temperature", String.valueOf(tempCelsius));
int humidity = jsonResponse.getJSONObject("main").getInt("humidity");
weather.put("humidity", Integer.toString(humidity));
} else {
System.out.println("Error: " + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
}
return weather;
}
}
=> index.html - WeatherService.java에서 가져온 weather_icon을 URL 사이에 삽입하기
<img th:src="'https://openweathermap.org/img/wn/' + ${weather['weather_icon']} + '@2x.png'" alt="Weather Icon" />
=> WeatherService.java - weather 배열의 객체에서 icon 속성의 value 값 찾아오기
// JSON 응답 파싱
JSONObject jsonResponse = new JSONObject(response.toString());
weather.put("weather_icon", jsonResponse.getJSONArray("weather").getJSONObject(0).getString("icon"));
▷ 출력
▣ 참고 자료 출처
'Project > AWS-Final' 카테고리의 다른 글
최종 프로젝트(10) - AWS 풀스택 과정 99일차 (0) | 2024.12.18 |
---|---|
최종 프로젝트(9) - AWS 풀스택 과정 98일차 (0) | 2024.12.17 |
최종 프로젝트(7) - AWS 풀스택 과정 96일차 (0) | 2024.12.13 |
최종 프로젝트(6) - AWS 풀스택 과정 95일차 (0) | 2024.12.12 |
최종 프로젝트(5) - AWS 풀스택 과정 94일차 (0) | 2024.12.11 |