기상청 api로 날씨 정보 가져오기

정윤서·2023년 12월 13일
0
post-custom-banner

1. 공공데이터 포털에서 api key 받기

기상청 단기예보 조회서비스

2. 현재 위치(좌표) 찾기

function success(position) {
   const lat = position.coords.latitude;
   const lon = position.coords.longitude;
   console.log(lat, lon);
}
function error() {
   alert("위치 정보를 불러올 수 없습니다.");
}
navigator.geolocation.getCurrentPosition(success, error);

이렇게 하면 콘솔에 사용자의 현재 위치의 x, y좌표가 표시된다.

3. 격자 좌표로 변환

기상청 api로 날씨 정보를 가져오기 위해서는 현재 좌표를 격자 좌표로 변환해야 한다.

function dfs_xy_conv(code, v1, v2) {
    var DEGRAD = Math.PI / 180.0;
    var RADDEG = 180.0 / Math.PI;

    var re = RE / GRID;
    var slat1 = SLAT1 * DEGRAD;
    var slat2 = SLAT2 * DEGRAD;
    var olon = OLON * DEGRAD;
    var olat = OLAT * DEGRAD;

    var sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
    sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
    var sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
    sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;
    var ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
    ro = re * sf / Math.pow(ro, sn);
    var rs = {};
    if (code == "toXY") {
        rs['lat'] = v1;
        rs['lng'] = v2;
        var ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);
        ra = re * sf / Math.pow(ra, sn);
        var theta = v2 * DEGRAD - olon;
        if (theta > Math.PI) theta -= 2.0 * Math.PI;
        if (theta < -Math.PI) theta += 2.0 * Math.PI;
        theta *= sn;
        rs['x'] = Math.floor(ra * Math.sin(theta) + XO + 0.5);
        rs['y'] = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);
    }
    else {
        rs['x'] = v1;
        rs['y'] = v2;
        var xn = v1 - XO;
        var yn = ro - v2 + YO;
        ra = Math.sqrt(xn * xn + yn * yn);
        if (sn < 0.0) - ra;
        var alat = Math.pow((re * sf / ra), (1.0 / sn));
        alat = 2.0 * Math.atan(alat) - Math.PI * 0.5;

        if (Math.abs(xn) <= 0.0) {
            theta = 0.0;
        }
        else {
            if (Math.abs(yn) <= 0.0) {
                theta = Math.PI * 0.5;
                if (xn < 0.0) - theta;
            }
            else theta = Math.atan2(xn, yn);
        }
        var alon = theta / sn + olon;
        rs['lat'] = alat * RADDEG;
        rs['lng'] = alon * RADDEG;
    }
    return rs;
}

4. 날씨 정보 가져오기

위치 정보를 가져오는 데 성공했을 때의 함수에 코드를 추가해야 한다.

const currentDateTime = getCurrentDateTime();

   var grid = dfs_xy_conv("toXY", lat, lon);
   var url = new URL("https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtFcst");
   var params = {
     serviceKey: "your_api_key",
     pageNo: 1,
     numOfRows: 60,
     dataType: 'json',
     base_date: currentDateTime.date,
     base_time: currentDateTime.time,
     nx: grid.x,
     ny: grid.y
   };

function getCurrentDateTime() {
    const now = new Date();

    const year = now.getFullYear();
    const month = (now.getMonth() + 1).toString().padStart(2, '0');
    const day = now.getDate().toString().padStart(2, '0');
    let hours = now.getHours();
    let minutes = '30';

    if (now.getMinutes() < 30) {
        hours -= 1;
    }

    if (hours < 0) {
        hours = '00';
    } else {
        hours = hours.toString().padStart(2, '0');
    }

    return {
        date: `${year}${month}${day}`,
        time: `${hours}${minutes}`
    };
}

기상청 api로 가져오는 날씨는 정확히 현재 날씨 정보가 아니라 6시간 뒤까지의 예보를 한시간 단위로 가져오기 때문에 가장 가까운 시간의 예보를 가져와야 한다.
그리고 예보는 매시 30분마다 업데이트 되기 때문에 날씨 정보를 가져올 때 들어갈 시간을 현재로부터 가장 가까운 과거의 30분을 가져와서 대입했다.

$.ajax({
      url: decodeURI(url),
      method: 'GET',
      dataType: 'json',
      success: function(data) {
          const dataList = data.response.body.items.item;

          var csrfHeader = $("meta[name='_csrf_header']").attr("content");
          var csrfToken = $("meta[name='_csrf']").attr("content");

          var weatherList = new Array();
          weatherList.push(dataList[6].fcstValue);
          weatherList.push(dataList[18].fcstValue);
          weatherList.push(dataList[24].fcstValue);
           error: function(err) {
          console.log('Ajax Error', err);
  }
});

이 코드에서 console.log(dataList);를 이용해 날씨 예보의 모든 정보를 json으로 확인할 수 있는데 나는 모든 정보가 필요한 게 아니라 현재 하늘의 상태, 강수 정보, 기온만 필요했기 때문에 필요한 정보의 값만 가져와 사용했다.

이렇게 가져온 값을 html에 대입하면 날씨 정보를 확인할 수 있다.

post-custom-banner

0개의 댓글