메뉴 건너뛰기

프로그래밍


Node.js에서 현재 기상정보 API를 호출하는 방법입니다.

- data.go.kr > 동네예보 조회서비스 > 초단기실황조회에 대한 API 활용 신청을 하여 키를 발급 받은 후 하기 코드의 'apikey' 값에 반영하여 사용하세요.

[ 참고 링크 ]


var http = require('http');

function getCurrentWeather(lat, lng){
    var rs = dfs_xy_conv("toXY", lat, lng);
    var _nx = rs.nx;
    var _ny = rs.ny;
    
    var today = new Date();
    today.setHours(today.getHours() + 9); //UTC환경일 경우 한국시간 기준으로 변경~
    
    var dd = today.getDate();
    var mm = today.getMonth()+1;
    var yyyy = today.getFullYear();
    var hours = today.getHours();
    var minutes = today.getMinutes();
 
    if(minutes < 30){
        // 30분보다 작으면 한시간 전 값
        hours = hours - 1;
        if(hours < 0){
            // 자정 이전은 전날로 계산
            today.setDate(today.getDate() - 1);
            dd = today.getDate();
            mm = today.getMonth()+1;
            yyyy = today.getFullYear();
            hours = 23;
        }
    }
    if(hours<10) {
        hours='0'+hours;
    }
    if(mm<10) {
        mm='0'+mm;
    }
    if(dd<10) {
        dd='0'+dd;
    } 
 
    var apikey = "data.go.kr > 동네예보 조회서비스 > 초단기실황조회 신청후 키 받기",
    ttoday = yyyy+""+mm+""+dd,
    basetime = hours + "00",
    fileName = "http://apis.data.go.kr/1360000/VilageFcstInfoService/getUltraSrtNcst";
    fileName += "?ServiceKey=" + apikey;
    fileName += "&base_date=" + ttoday;
    fileName += "&base_time=" + basetime;
    fileName += "&nx=" + _nx + "&ny=" + _ny;
    fileName += "&pageNo=1&numOfRows=10";
    fileName += "&dataType=JSON";
  
    var path = fileName;
    http.get(path, (resp) => {
      let data = '';
      // A chunk of data has been recieved.
      resp.on('data', (chunk) => {
        data += chunk;
      });
  
      // The whole response has been received. Print out the result.
      resp.on('end', () => {
        var ret = JSON.parse(data);
        makeResponse(ret, callback);
      });
  
    }).on("error", (err) => {
      console.log("Error is : " + err.message);
    });
}
 
function makeResponse(ret, callback) {
    
    var pty, reh, rn1, t1h, uuu, vec, vvv, wsd;
    ret.response.body.items.item.forEach(function(it) {
        if (it.category == "PTY")
            pty = it.obsrValue;
        else if (it.category == "REH")
            reh = it.obsrValue;
        else if (it.category == "RN1")
            rn1 = it.obsrValue;
        else if (it.category == "T1H")
            t1h = it.obsrValue;
        else if (it.category == "UUU")
            uuu = it.obsrValue;
        else if (it.category == "VEC")
            vec = it.obsrValue;
        else if (it.category == "VVV")
            vvv = it.obsrValue;
        else if (it.category == "WSD")
            wsd = it.obsrValue;            
    });
    
    //우천 여부와 온도, 풍속만 표시해 봅니다
    //없음(0), 비(1), 비/눈(2), 눈(3), 소나기(4)
    if (pty == 0) {
        pty = "sun";
    }
    else if (pty == 1) {
        pty = "rain";
    }
    else if (pty == 2) {
        pty = "rain/snow";
    }
    else if (pty == 3) {
        pty = "snow";
    }
    else if (pty == 4) {
        pty = "rain";
    }
    
    return ({temp : t1h, wind : wsd, pty: pty});    
}


// https://gist.github.com/fronteer-kr/14d7f779d52a21ac2f16 에서 가져 왔습니다.
// LCC DFS 좌표변환을 위한 기초 자료
//
var RE = 6371.00877; // 지구 반경(km)
var GRID = 5.0; // 격자 간격(km)
var SLAT1 = 30.0; // 투영 위도1(degree)
var SLAT2 = 60.0; // 투영 위도2(degree)
var OLON = 126.0; // 기준점 경도(degree)
var OLAT = 38.0; // 기준점 위도(degree)
var XO = 43; // 기준점 X좌표(GRID)
var YO = 136; // 기1준점 Y좌표(GRID)
//
// LCC DFS 좌표변환 ( code : "toXY"(위경도->좌표, v1:위도, v2:경도), "toLL"(좌표->위경도,v1:x, v2:y) )
//
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['nx'] = Math.floor(ra * Math.sin(theta) + XO + 0.5);
        rs['ny'] = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);
    }
    else {
        rs['nx'] = v1;
        rs['ny'] = 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;
}
// dfs_xy_conv


하기 블로그의 코드를 참고하였습니다.

http://naminsik.com/blog/3011 ]





번호 제목 글쓴이 날짜 조회 수
공지 [TIP] PYTHON 에서 "UnicodeDecodeError: 'cp949' codec can't decode byte 0xe2 in position 6987: illegal multibyte sequence" 오류 날때... [28] 파이팅건맨 2016.02.20 61717
공지 [TIP] TensorFlow를 윈도우에서 사용하기 (A way to use TensorFlow on Windows) [3] 파이팅건맨 2016.04.16 9773
공지 [TIP] JQuery와 PHP로 이미지 파일을 업로드 하는 간단한 소스 (How to upload image file on PHP server by using JQuery) 파이팅건맨 2015.04.03 8886
» [TIP] Node.js 에서 현재 기상정보 API 호출하기 파이팅건맨 2020.02.22 46
162 [TIP] gcc 빌드중에 /usr/bin/ld: errno: TLS definition in /lib64/libc.so.6 section .tbss mismatches non-TLS reference in ... 와 같은 오류를 만났을 때 파이팅건맨 2019.11.25 122
161 [TIP] Windows UWP에서 시리얼 포트가 열리지 않을때 파이팅건맨 2019.11.08 397
160 [TIP] 화면 스크롤시 HTML Element가 화면의 중간에 위치하면 감지하기 파이팅건맨 2019.10.03 359
159 [TIP] Visual Studio 2019 에서 (배포용)설치파일 만들기 파이팅건맨 2019.09.30 1224
158 [TIP] Android에서 MS의 Face Rest API사용하기 (How to use the MS Face API on Android) 파이팅건맨 2019.07.16 380
157 [TIP] Xcode에서 boost 사용하는 방법 파이팅건맨 2019.06.28 149
156 [TIP] 아두이노에서 두근두근 Open API 호출하기 파이팅건맨 2019.06.04 494
155 [TIP] AWS Lambda, API Gateway 를 이용하여 S3에 파일 업로드 하기 파이팅건맨 2018.06.12 1635
154 [TIP] 파이선에서 AWS Lambda API 호출시 Cognito 사용자 토큰으로 권한 확인하기 파이팅건맨 2018.06.11 733
153 [TIP] 파이선에서 AWS Cognito 에 Sign-up, Sign-in 하는 예제 파이팅건맨 2018.06.08 626
152 [TIP] Ajax에서 AWS Lambda Rest API CALL 하기 (How to call AWS Lambda API from Ajax) 파이팅건맨 2018.02.12 733
151 [TIP] 나만의 OpenAPI 배포 플랫폼 만들기 [6] 파이팅건맨 2018.01.30 960
150 [TIP] 파이선에서 AWS Lambda로 만든 Restful API 호출하기 (How to call AWS Lambda Restful API from Python) 파이팅건맨 2018.01.23 535
149 [TIP] 파이선에서 서브프로세스를 실행시키고 출력되는 내용을 얻어오기 파이팅건맨 2018.01.22 2620
148 [TIP] 아두이노에서 AWS Lambda로 제작한 Restful API 호출하기 (The way how to call AWS Lambda Restful API from Arduino) 파이팅건맨 2018.01.18 615
147 [TIP] 파이선에서 Redis 이벤트 받기 파이팅건맨 2017.10.12 673
146 [TIP] 파이선에서 SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position ... 오류 해결 방법 파이팅건맨 2017.09.29 1605
145 [TIP] The function size must be used with a prefix when a default namespace is not specified 오류 해결하기 파이팅건맨 2017.08.02 1641
144 [TIP] 페이스북 개인 담벼락의 좋아요수 크롤링하기 파이팅건맨 2017.07.15 1134
위로