givepro

공공데이터 날씨 API 활용 본문

백엔드/SpringBoot

공공데이터 날씨 API 활용

givepro 2022. 10. 28. 14:32
반응형

특정 통계 페이지에서 과거 날씨 정보가 필요하여 공공데이터의 날씨 데이터를 활용 할 수 있도록 해봤습니다.

지금 작성하는 기준은 당시 프로젝트의 비즈니스 로직에 따라서 진행하다보니 효율적이지 않을 수도 있습니다. 참고해주세요.

 

1. 날씨 Entity 생성

/** 생략 **/
public class WeatherSimpleInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    public Integer day;
    public Integer year;

    public String month_1;
    public String month_2;
    public String month_3;
    public String month_4;
    public String month_5;
    public String month_6;
    public String month_7;
    public String month_8;
    public String month_9;
    public String month_10;
    public String month_11;
    public String month_12;
}

매년 1월 1일이 되면 해당 년도의 row를 생성하는 스케줄링이 필요

 

2. 과거 날씨 정보 추출 및 DB Insert

  • 기상철 날씨누리 사이트의 요소별 자료를 참고 (링크)
    • API를 활용해서 과거 날씨 정보를 가져 올 수 있으나 다른방식으로 접근함
    • HTML 코드 활용 → JSON 추출
<script>
    function tableToJson(table) { // 변환 함수
        var data = [];
        var oriHeadText;
        var headers = [];
        for(var i=0; i<table.rows[0].cells.length; i++) {
            oriHeadText = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
            oriHeadText = oriHeadText.replace(/(<([^>]+)>)/ig,"").trim();
            if (oriHeadText == "일자") {
                oriHeadText = "day";
            } else if (oriHeadText.indexOf('월')) {
                oriHeadText = oriHeadText.replace(/월/g, "");
                oriHeadText = "month_" + oriHeadText;
            }
            headers[i] = oriHeadText;
        }

        headers[i+1] = "year";

        for(var i=1; i<table.rows.length; i++) {
            var tableRow = table.rows[i];
            var oriText;
            var rowData = {};

            for(var j=0; j<tableRow.cells.length; j++) {
                oriText = tableRow.cells[j].innerHTML;
                oriText = oriText.replace(/\n/gi, '');
                oriText = oriText.replace(/(<([^>]+)>)/ig,"").trim();
                if (oriText == "&nbsp;") {
                    oriText = "";
                } else if (oriText.length > 1) {
                    // oriText = oriText.replace(/ /gi, ',');
                    oriText = oriText.replace(/ +/g, " ");
                    oriText = oriText.replace(/ /gi, ',');
                }

                // {숫자}일 인 경우 {숫자}만 표기하도록 정규식 조건 처리
                var dayReg = /^[0-9]*일/g
                if (dayReg.test(oriText)) {
                    oriText = oriText.replace(/일/g, "");
                }

                rowData[headers[j]] = oriText;
            }
            rowData[headers[j+1]] = "2022";
            data.push(rowData);
        }

        return data;
    }
</script>

3. 어제 날씨 정보 스케줄러

서버에서 스케줄 기능을 사용하기 위해서는 아래와 같이 메인 클래스에서 추가를 해야한다. @EnableScheduling 

@EnableScheduling
@EntityScan(basePackageClasses = {Admin.class, Jsr310JpaConverters.class} )
public class Admin {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Admin.class, args);
    }
}

스케줄링을 진행할 메소드 생성

@Scheduled(cron = "0 0 6 * * *")
public void getWeatherInfo() {
    생략..
}

4. 오늘 실시간 날씨

try {
    JSONParser parser = new JSONParser();
    JSONObject obj = (JSONObject) parser.parse(result);
    JSONObject parseResponse = (JSONObject) obj.get("response");
    JSONObject parseBody = (JSONObject) parseResponse.get("body");
    JSONObject parseItems = (JSONObject) parseBody.get("items");
    JSONArray parseItem = (JSONArray) parseItems.get("item");

    String category;
    JSONObject weather;

    String day = "";
    String time = "";

    for (Object row : parseItem) {
        weather = (JSONObject) row;
        Object fcstValue = weather.get("fcstValue");
        Object fcstDate = weather.get("fcstDate");
        Object fcstTime = weather.get("fcstTime");

        category = (String) weather.get("category");
        if(!day.equals(fcstDate.toString())) {
            day=fcstDate.toString();
        }
        if(!time.equals(fcstTime.toString())) {
            time=fcstTime.toString();
        }

        if (!todayResult.containsKey("SKY") && category.equals("SKY")) {
            todayResult.put("SKY", skyConvert(fcstValue.toString()));
        }
        if (!todayResult.containsKey("T1H") && category.equals("T1H")) {
            todayResult.put("T1H", fcstValue.toString() + "℃");
        }
    }

} catch(Exception e) {
    e.printStackTrace();
}

 


참고 사이트

공공데이터 포털

Java 기상청 날씨 API 사용하기(동네예보조회)

기상청 격자정보 - 위경도 변환 Grid XY - Lat, Lon

날씨누리

 

 

 

Comments