💡공공데이터 날씨 API 이용
🗨️ 현재 위치값으로 날씨정보 가져와서 보여주기
현재 위치값 가져오기
// 브라우저에서 현재 위치값 가져오는 API
navigator.geolocation.getCurrentPosition(success, error);
function success(position) {
// 실제 포지션 값 (위도, 경도)
const lat = position.coords.latitude;
const lon = position.coords.longitude;
// 기상청 API에 적용할 수 있게 가공
const result = dfs_xy_conv(lat, lon); // 기상청 공식 함수
nx = result.nx;
ny = result.ny;
console.log("현재 격자 좌표:", nx, ny); // 좌표 찍어보기
getWeather(nx, ny) //현재 날씨 구하는 함수 실행
}
브라우저 내장 함수를 사용하여 구함
브라우저 실행 시 위치값 권한 요청. 요청 거절시 데이터 미출력
현재 시간을 구해서 데이터 알맞게 가공
현재 날짜 및 시간 구하는 로직 실행
AM 2시를 기준으로 3시간 간격마다 날씨를 제공하기에, 그 시간에 맞게 가공
해당 시간이 아닐시 에러
//현재 날짜를 양식에 맞게 조절 (yyyymmdd)
const base_date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
//현재 시간기준으로 양식에 맞는 시간 구함
const base_time = getBaseTime();
//날짜 가공 함수
function getBaseTime() {
//현재 시간
const now = new Date();
const hour = now.getHours();
// 기상청 지원 base 시간 정리
const times = [2, 5, 8, 11, 14, 17, 20, 23];
let baseHour = 23; // 기본값 (가장 늦은 시간)
// bases 시간 기준으로 규격에 맞는 시간만 구함
for (let i = 0; i < times.length; i++) {
if (hour < times[i]) {
baseHour = times[i - 1] ?? 23; // 제일 이른 시간 전이면 23시 (전날)
break;
}
}
//해당 시간을 양식에 맞게 정리 (0200 ~ 2300)
return String(baseHour).padStart(2, '0') + '00';
}
시간과 좌표 기준으로 날씨 정보 구함
공공데이터포탈 API 키 필요
해당 키를 사용하여 Json 형식으로 된 url 접근 가능
현재 기온은 숫자로, 현재 날씨 상태는 아이콘 형식으로(FontAwesome 사용) 변환하여 사용
// 날씨 정도 가져오는 함수
function getWeather(nx, ny) {
// 오늘 날짜와 적절한 base_time 계산
const base_date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
const base_time = getBaseTime(); //3시간 단위 (0500, 0800 ...)
// 날씨 API 에서 인코딩된 키 사용
const serviceKey = "[발급받은 Key]";
// 좌표와 시간, 날짜, key 사용하여 url 생성
const url = `https://apis.data.go.kr/1360000/
VilageFcstInfoService_2.0/
getVilageFcst?serviceKey=${serviceKey}&pageNo=1&
numOfRows=1000&dataType=JSON&base_date=${base_date}&
base_time=${base_time}&nx=${nx}&ny=${ny}`;
//url 사용하여 json 파일로 된 데이터에서 필요한 부분 생성
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error("네트워크 응답에 문제가 있습니다.");
}
return response.json();
})
.then(data => {
const items = data.response.body.items.item;
// 예보 시간 기준으로 정렬 (선택 사항)
const forecast = {};
// TMP는 온도, SKY는 상태(맑음,흐림), PTY는 기상(눈,비)
items.forEach(item => {
const time = item.fcstTime;
if (!forecast[time]) forecast[time] = {};
if (item.category === "TMP") {
forecast[time].temp = item.fcstValue;
} else if (item.category === "SKY") {
forecast[time].sky = item.fcstValue;
} else if (item.category === "PTY") {
forecast[time].pty = item.fcstValue;
}
});
// 상태 매핑 (FontAwesome 아이콘 사용)
const skyMap = {
"1": "fas fa-sun", // 맑음
"3": "fas fa-cloud-sun", // 흐림
"4": "fa-solid fa-smog" // 구름
};
const ptyMap = {
"0": "없음",
"1": "fa-solid fa-umbrella", // 비
"2": "fa-solid fa-cloud-meatball", // 비/눈
"3": "fa-solid fa-snowflake", // 눈
"4": "fa-solid fa-cloud-showers-heavy", // 소나기
"5": "fa-solid fa-cloud-rain", // 비
"6": "fa-solid fa-cloud-meatball", // 함박눈
"7": "fa-solid fa-cloud-meatball" // 함박눈
};
// 시간 정보
const forecastTimes = Object.keys(forecast);
// 전체 예보 시간 중 첫 번째 항목만 선택
if (forecastTimes.length > 0) {
const selectedTime = forecastTimes[0];
const tmp = forecast[selectedTime].temp;
let status = null;
// 맑은, 흐림, 비, 눈 선택
if (forecast[selectedTime].pty == 0) {
status = skyMap[forecast[selectedTime].sky];
} else {
status = ptyMap[forecast[selectedTime].pty];
}
// 날씨 양식 Text 파일로 변경 후 innerHTML로 입력
let whetherTag = `<i class="${status}"></i> ${tmp}°C`
document.getElementById("header_whether").innerHTML = whetherTag;
} else {
console.log("예보 정보가 없습니다.");
}
})
.catch(error => {
console.error("날씨 정보를 가져오는 데 실패했습니다:", error);
});
}
