2024. 8. 21. 18:41ㆍFCB2O4
오늘은 날씨 위젯을 완성시키기.
우선 날씨 위젯에서 오늘 포함 5일간의 일기예보를 보여주도록 표시하기위해 요일 계산기를 만들었다.
먼저 기존의 미래날짜 계산기에서 length를 3에서 5로 변경
const futureDates = Array.from({ length: 5 }, (_, i) =>
new Date(current + oneDay * i).toISOString().slice(0, 10) + DesiredTime
);
그리고 저기서 생성된 5개의 날짜를 전달 받아 요일로 변환해주는 함수
//요일 계산
const getDayOfWeek = (dateStr) => {
const daysOfWeek = ["일", "월", "화", "수", "목", "금", "토"];
const date = new Date(dateStr);
return daysOfWeek[date.getDay()];
};
그런데 날씨 위젯에서 이름이 JamWon-Dong으로 표시되는 현상 발생.
나는 서울, 인천 같은 시/도 단위의 날씨를 보여주고 싶은데 동 단위라는 너무 좁은 단위의 날씨를 보여주고 있는 문제.
그래서 사용자 좌표를 역으로 거슬러 올라가 그 좌표가 속한 시/도를 계산하도록 했다.
const getCityStateName = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json&addressdetails=1`)
const cityOrState = await getCityStateName.json();
const locationName = cityOrState.address.city || cityOrState.address.state;
nominatim을 이용해 좌표를 역추적해 시(city)/도(state)를 반환.
그리고 이 지명을 이용해 그곳의 날씨 정보를 얻어오기 위해
const responseCurrent = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${locationName}&appid=${key}&units=metric&lang=KR`,
);
console.log(`https://api.openweathermap.org/data/2.5/weather?q=Seoul&appid=${key}&units=metric&lang=KR`);
const responseForecast = await fetch(
`https://api.openweathermap.org/data/2.5/forecast?q=${locationName}&appid=${key}&units=metric&lang=KR`,
);
fetch로 좌표에서 직접 얻어오는 것이 아닌 도시의 이름을 넣어 도시의 날씨를 얻어오도록 수정.
그런데 날씨 정보를 가져올 수 없는 문제가 발생.
이유를 알아보니 nominatim에서 반환되는 지역의 이름이 한글이었던 것.
즉, 받는 주소에서 ${locationName} 부분이 Seoul 이 아니라 이상한 문자로 깨져버려 날씨 정보를 가져올 수 없었다.
이를 위해 nominatim에서 한글이 아닌 영어로 지명을 받아오기 위해 다음 문구를 추가했다.
const getCityStateName = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json&addressdetails=1`, {
headers: {
'Accept-Language': 'en'
}
})
headers를 통해 영어로 받아들인다고 선언.
드디어 동 단위가 아닌 시/도 단위의 날씨를 받아오는 데 성공.
본래는 여기까지 할 생각이었으나, 욕심이 생겨 날씨에 따른 배경사진을 넣고자 했다.
먼저 맑음, 바람, 비, 눈 등 8가지 기초 기상현상의 사진들을 구한 후 각각 이름 붙이고
<div className='weather-widget'
style={{ backgroundImage: `url(${process.env.PUBLIC_URL}/images/${getBackgroundImage(weatherValue)})` }}>
변수를 통해 이미지를 상황에 따라 바꿔야하므로 따로 css 파일에서 백그라운드 이미지를 주는 것이 아니라 해당 파일에서 이미지를 불러오도록 했다.
// 날씨 상태에 따라 배경 이미지 선택하기
const getBackgroundImage = (weather) => {
if (!weather) return '';
const mainWeather = weather.weather[0].main;
switch (mainWeather) {
case 'Clear':
return 'sunny.jpg';
case 'Clouds':
return 'cloudy.jpg';
case 'Rain':
return 'rainy.jpg';
case 'Snow':
return 'snowy.jpg';
case 'Thunderstorm':
return 'thunderstorm.jpg';
case 'Fog':
return 'foggy.jpg';
case 'Breeze':
return 'windy.jpg';
case 'Hail':
return 'hail.webp';
default:
return 'sunny.jpg';
}
};
그리고 날씨(WeatherValue)에 따라 이미지가 실시간으로 변경될 수 있도록 switch을 작성.
그런데 에러가 발생했다. 로그를 찍어보니 분명히 경로는 맞는데 이미지를 불러오질 못하는 것.
원인은 사진명에 (날씨배경)이라는 이름을 넣었던 것. 한글을 넣어서 파일명이 깨져버렸던 것이다.
그래서 한글명을 모두 삭제하고 영어명만 남겼다.
성공했다. 현재 날씨가 흐림이라 cloudy 사진을 불러온 상태.
오늘은 여기까지. 이제 내 역할은 거의 마무리 된 상태. 이제 내가 맡은 부분들의 css에 집중하면 된다.