본문 바로가기

데이터분석/탐구

탐구 - 기상청 API를 활용한 날씨 사이트 만들기 (3)-최종ㅎㅎㅎ

728x90

HTML, CSS, JavaScript로 나누어 코드를 보여준 후, 각각의 부분에 대해 설명하겠습니다.

HTML 코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>날씨 정보</title>
    <link rel="stylesheet" href="styles.css">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet"> <!-- 구글 폰트 -->
</head>
<body>
    <div class="container">
        <h1>🌤 지역별 날씨 정보</h1>
        <div class="location-select">
            <label for="location">지역 선택:</label>
            <select id="location">
                <option value="">지역을 선택하세요</option>
                <option value="서울">서울특별시</option>
                <option value="부산">부산광역시</option>
                <option value="대구">대구광역시</option>
                <option value="인천">인천광역시</option>
                <option value="광주">광주광역시</option>
                <option value="대전">대전광역시</option>
                <option value="울산">울산광역시</option>
                <option value="세종">세종특별자치시</option>
                <option value="경기">경기도</option>
                <option value="강원">강원도</option>
                <option value="충북">충청북도</option>
                <option value="충남">충청남도</option>
                <option value="전북">전라북도</option>
                <option value="전남">전라남도</option>
                <option value="경북">경상북도</option>
                <option value="경남">경상남도</option>
                <option value="제주">제주특별자치도</option>
            </select>
            <button id="getWeather">날씨 조회</button>
        </div>

        <div id="weatherResult">
            <h2>날씨 결과:</h2>
            <div id="weatherDetails"></div>
        </div>
    </div>

    <script src="app.js"></script>
</body>
</html>

HTML 설명

  • 문서 구조: HTML 문서는 기본적인 웹 페이지 구조를 따릅니다. <head> 섹션에는 메타데이터와 스타일시트 링크가 포함되어 있습니다.
  • 제목 및 지역 선택: <h1> 태그로 제목을 표시하고, <select> 태그를 사용하여 사용자가 지역을 선택할 수 있습니다.
  • 버튼: "날씨 조회" 버튼은 사용자가 선택한 지역의 날씨 정보를 조회하는 기능을 수행합니다.
  • 결과 표시 영역: 날씨 결과를 보여줄 <div> 요소가 있습니다.

CSS 코드

/* 기본 스타일 */
body {
    font-family: 'Roboto', sans-serif;
    background: linear-gradient(to top, #a8edea, #fed6e3);
    color: #333;
    margin: 0;
    padding: 0;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    text-align: center;
    background-color: rgba(255, 255, 255, 0.85);
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    margin-top: 50px;
}

h1 {
    font-size: 2.5em;
    margin-bottom: 20px;
    color: #00796b;
}

.location-select {
    margin: 20px 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}

label {
    font-weight: bold;
    margin-bottom: 10px;
}

select, button {
    padding: 10px;
    font-size: 16px;
    border-radius: 5px;
    border: 1px solid #00796b;
    margin-bottom: 20px;
    width: 100%;
    max-width: 300px;
}

button {
    background-color: #00796b;
    color: white;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

button:hover {
    background-color: #004d40;
}

#weatherResult {
    margin-top: 30px;
}

#weatherDetails {
    background-color: #f9f9f9;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    text-align: left;
    font-size: 1.1em;
}

#weatherDetails p {
    margin: 10px 0;
    display: flex;
    align-items: center;
}

#weatherDetails p::before {
    content: "🌡️";
    margin-right: 10px;
}

/* 반응형 디자인 */
@media (max-width: 600px) {
    h1 {
        font-size: 2em;
    }

    select, button {
        width: 100%;
    }

    #weatherDetails {
        font-size: 1em;
    }
}

CSS 설명

  • 기본 스타일: 전체 페이지에 적용할 기본 폰트와 배경을 설정합니다. 그라디언트 배경이 사용되었습니다.
  • 컨테이너: 최대 폭과 중앙 정렬을 설정하여 콘텐츠를 보기 좋게 배치합니다.
  • 버튼 및 선택창: 버튼과 선택창의 스타일을 지정하여 사용자 경험을 개선합니다. 버튼에 마우스를 올렸을 때 색상이 변화하는 효과도 있습니다.
  • 날씨 결과 표시: 날씨 정보를 표시할 영역의 스타일을 설정하여 시각적으로 구분되도록 합니다.
  • 반응형 디자인: 화면 크기에 따라 폰트 크기와 요소의 크기를 조정합니다.

물론입니다! JavaScript 코드를 이어서 작성하겠습니다.

JavaScript 코드 (계속)

        '인천': { nx: 55, ny: 124 },
        '광주': { nx: 58, ny: 74 },
        '대전': { nx: 67, ny: 100 },
        '울산': { nx: 102, ny: 84 },
        '세종': { nx: 66, ny: 103 },
        '경기': { nx: 60, ny: 120 },
        '강원': { nx: 73, ny: 134 },
        '충북': { nx: 69, ny: 107 },
        '충남': { nx: 68, ny: 100 },
        '전북': { nx: 63, ny: 89 },
        '전남': { nx: 50, ny: 67 },
        '경북': { nx: 89, ny: 91 },
        '경남': { nx: 91, ny: 77 },
        '제주': { nx: 52, ny: 38 }
    };

    const coords = locationCoordinates[location];
    if (!coords) {
        alert('해당 지역의 좌표를 찾을 수 없습니다.');
        return;
    }

    const { nx, ny } = coords;
    const apiKey = '공공데이터포털에서 받은 인증키'; // 공공데이터포털에서 받은 인증키 입력
    const baseDate = new Date().toISOString().slice(0, 10).replace(/-/g, '');
    const baseTime = '0600'; // 예시로 06시 정시 데이터 사용

    const url = `http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst?serviceKey=${apiKey}&pageNo=1&numOfRows=10&dataType=JSON&base_date=${baseDate}&base_time=${baseTime}&nx=${nx}&ny=${ny}`;

    fetch(url)
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            const items = data.response.body.items.item;
            displayWeather(items);
        })
        .catch(error => {
            console.error('Fetch error:', error);
            alert('날씨 데이터를 가져오는 데 실패했습니다.');
        });
});

function displayWeather(items) {
    const weatherDetails = document.getElementById('weatherDetails');
    weatherDetails.innerHTML = ''; // 초기화

    items.forEach(item => {
        const category = getCategoryName(item.category);
        const obsrValue = item.obsrValue;

        const weatherItem = document.createElement('p');
        weatherItem.innerText = `${category}: ${obsrValue}`;
        weatherDetails.appendChild(weatherItem);
    });
}

function getCategoryName(category) {
    switch (category) {
        case 'RN1': return '강수량 (mm)';
        case 'T1H': return '기온 (℃)';
        case 'UUU': return '동서바람 성분 (m/s)';
        case 'VVV': return '남북바람 성분 (m/s)';
        case 'WSD': return '풍속 (m/s)';
        default: return '기타';
    }
}

JavaScript 설명

  • 이벤트 리스너: "날씨 조회" 버튼 클릭 시, 사용자가 선택한 지역을 가져와서 유효성을 검사합니다. 지역이 선택되지 않았거나 좌표가 없으면 경고 메시지를 표시합니다.

  • 좌표 설정: 지역별 좌표를 설정하기 위해 객체를 사용합니다. 사용자가 선택한 지역의 좌표를 찾고, 해당 좌표가 없으면 오류 메시지를 표시합니다.

  • API 호출: 유효한 좌표가 확인되면, 공공 API를 통해 날씨 데이터를 요청하는 URL을 생성하고 fetch 메서드를 사용하여 데이터를 가져옵니다. 이때, 현재 날짜와 시간을 기반으로 요청을 구성합니다.

  • 데이터 처리: API 응답이 성공적이면 JSON 형식으로 변환하여 날씨 정보를 표시하는 displayWeather 함수를 호출합니다. 오류가 발생할 경우 오류 메시지를 콘솔에 출력하고 사용자에게 알림을 표시합니다.

  • 날씨 정보 표시: displayWeather 함수는 날씨 정보를 화면에 출력합니다. 각 날씨 항목은 getCategoryName 함수를 통해 적절한 카테고리 이름으로 변환됩니다.

  • 카테고리 이름 변환: getCategoryName 함수는 날씨 데이터의 카테고리 코드에 따라 적절한 설명을 반환합니다.


결론

이 싸이트는 사용자가 지역을 선택하여 해당 지역의 날씨 정보를 실시간으로 조회할 수 있도록 설계되었습니다. HTML, CSS, JavaScript가 잘 결합되어 사용자의 경험을 향상시키는 동시에, 공공 API를 통해 실시간 데이터를 제공하는 기능을 구현하고 있습니다.

728x90