티스토리 뷰

기상청 날씨정보



)?제가 여러곳에서 기상청 데이터 파싱방법을 찾아본 결과 여러방법들이 존재하고 있었습니다.

대표적으로?1. 기상청에서 제공하는 동네코드를 알아낼 수 있는 url을 활용http://javaking75.blog.me/220091928699 [Java] ??? ???? ? ??? ?? ??? ????[??]???? (pluulove84) ??? - ??? ???? ??(?)?? : http://blog.naver.com/pluulove84/...blog.naver.com-> 단점 : 일부 지역은 포함하고있지 않아 모든 지역의 동네코드를 얻어올 수 없었습니다.

2. 기상청 RSS 활용http://www.kma.go.kr/weather/lifenindustry/sevice_rss.jspRSS > ??? > ??? > ??? ?? > ?? > ???www.kma.go.kr- 단점 : 동네 기상정보를 한 번에 한지역만 조회가가능 합니다.

3. 위도와 경도를 이용하여 GridX, GridY좌표 구해서 동네 예보가져오기 (가장  좋은 방법 같습니다.

)http://javaking75.blog.me/220089575454[JavaScript] ??? ???? ?? - ??? ( Grid XY - Lat, Lon ) : ?? ...???? http://www.kma.go.kr/weather/forecast/timeseries.jsp ???? ???? XML ??? ???...blog.naver.com* 이러한 방법들을 짬뽕하여 "지역 이름"을 하면 1. 구글 Geolocation 서비스를 이용하여 위도 경도 획득하고2. 위도, 경도를 기상청에서 만들어놓은 GridX, GridY를 구하는 공식을 이용하여 GridX,Y좌표를 구하여 동네주간예보를 가져오겠습니다.

시작!-1단계구글 Geolocation 서비스를 이용하여 "지역명"으로 위도(Longtitude),경도(Latitude) 가져오기*요청 URLhttp://maps.google.com/maps/api/geocode/json?address=지역이름ex) http://maps.google.com/maps/api/geocode/json?address=대전 서구 관저동아래처럼 크롬브라우저에다가 해당 url을 하게 되면이와 같이 JSON형태의 위치에 해당하는 정보들을 가져오게 됩니다.

여기서 필요한 정보는 location 의 "lat" , "lng" 의 정보입니다.

 * Json데이터를 손쉽게 추출하기위해서 아래 라이브러리를 사용하였습니다.

메이븐이나, 다운로드를 통해서 빌드시켜주세요http://www.mvnrepository.com/artifact/com.googlecode.json-simple/json-simple/1.1.1Maven Repository: com.googlecode.json-simple � json-simple � 1.1.1www.mvnrepository.com- lat, lng 좌표 가져오기1234567891011121314151617181920212223242526272829303132333435        String json;        StringBuilder sb = new StringBuilder();        double v1 = 0.0;        double v2 = 0.0;        try {            String location = "대전 서구 관저동";            String addr = "http://maps.google.com/maps/api/geocode/json?address=";            URL url = new URL(addr + URLEncoder.encode(location, "UTF-8"));            HttpURLConnection con = (HttpURLConnection) url.openConnection();            con.setConnectTimeout(10000);            con.setUseCaches(false);            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));             while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            br.close();            con.disconnect();        } catch (Exception e) {            System.out.println(e.getMessage());        }        json = sb.toString();        JSONObject object = (JSONObject) JSONValue.parse(json);        JSONArray array = (JSONArray) object.get("results");        for (Object o : array) {            JSONObject object2 = (JSONObject) o;            String lat = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lat").toString();            String lng = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lng").toString();             v1 = Double.parseDouble(lat);            v2 = Double.parseDouble(lng);        }Colored by Color Scriptercsv1, v2에 각각 위도와 경도를 저장하였습니다.

?2. 위도, 경도를 가지고 Gridx, Gridy 좌표 구하기위도 경도를 Gridx, Gridy좌표로 변경시켜주는 getGridxy함수의 매개변수에 이전에 얻어온 위도,경도(v1,v2)값을 넣으면됩니다.

 12345678910111213141516171819202122232425262728293031323334353637383940414243    double RE = 6371.00877; // 지구 반경(km)    double GRID = 5.0; // 격자 간격(km)    double SLAT1 = 30.0; // 투영 위도1(degree)    double SLAT2 = 60.0; // 투영 위도2(degree)    double OLON = 126.0; // 기준점 경도(degree)    double OLAT = 38.0; // 기준점 위도(degree)    double XO = 43; // 기준점 X좌표(GRID)    double YO = 136; // 기1준점 Y좌표(GRID)     public Map<String, Object> getGridxy(double v1, double v2) {         double DEGRAD = Math.PI / 180.0;        // double RADDEG = 180.0 / Math.PI;         double re = RE / GRID;        double slat1 = SLAT1 * DEGRAD;        double slat2 = SLAT2 * DEGRAD;        double olon = OLON * DEGRAD;        double olat = OLAT * DEGRAD;         double 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);        double sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);        sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;        double ro = Math.tan(Math.PI * 0.25 + olat * 0.5);        ro = re * sf / Math.pow(ro, sn);        Map<String, Object> map = new HashMap<String, Object>();        map.put("lat", v1);        map.put("lng", v1);        double ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);        ra = re * sf / Math.pow(ra, sn);        double theta = v2 * DEGRAD - olon;        if (theta > Math.PI)            theta -= 2.0 * Math.PI;        if (theta < -Math.PI)            theta += 2.0 * Math.PI;        theta *= sn;         map.put("x", Math.floor(ra * Math.sin(theta) + XO + 0.5));        map.put("y", Math.floor(ro - ra * Math.cos(theta) + YO + 0.5));         return map;    }Colored by Color Scriptercs?* Map형태로 "x", "y"키 값에 각각 Gridx, Gridy값을 저장하였습니다.

 3. 위에서 얻은 Gridx,Gridy 값으로 동네 xml데이터 얻기* 요청 urlhttp://www.kma.go.kr/wid/queryDFS.jsp?gridx=x좌표&gridy=y좌표ex) http://www.kma.go.kr/wid/queryDFS.jsp?gridx=66gridy=99 (대전 서구 관저동 날씨)아래와 같은 xml데이터를 리턴합니다.

- 동네 예보 xml 태그 설명서http://www.kma.go.kr/images/weather/lifenindustry/timeseries_XML.pdf123456789101112131415161718192021222324String xml = "";        try {            // 전국 날씨정보            String addr = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + map.get("x") + "&gridy=" + map.get("y");            URL url = new URL(addr);            HttpURLConnection http = (HttpURLConnection) url.openConnection();            http.setConnectTimeout(10000);            http.setUseCaches(false);             BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));            sb = new StringBuilder();            while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            xml = sb.toString();            br.close();            http.disconnect();         } catch (Exception e) {            System.out.println("다운로드에러" + e.getMessage());        }Colored by Color Scriptercs4. XML기상 정보 파싱1234567891011121314151617181920212223242526272829303132333435363738        Map<String, Object> data = new HashMap<String, Object>();        try {            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder documentbuilder = factory.newDocumentBuilder();            InputStream is = new ByteArrayInputStream(xml.getBytes());            Document doc = documentbuilder.parse(is);            Element element = doc.getDocumentElement();             NodeList list1 = element.getElementsByTagName("data");             for (int i = 0; i < list1.getLength(); i++) {                for (Node node = list1.item(i).getFirstChild(); node != null; node = node.getNextSibling()) {                     if (node.getNodeName().equals("hour")) {                        System.out.println("----------------------------");                        data = new HashMap<String, Object>();                        data.put("hour", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("temp")) {                        data.put("temp", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("reh")) {                        data.put("reh", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("wfEn")) {                        data.put("wfEn", node.getTextContent().toString());                        list.add(data);                    }                }            }         } catch (Exception e) {            System.out.println("파싱에러" + e.getMessage());        }        System.out.println(data);Colored by Color Scriptercs*결과?전체코드 (*JSON라이브러리만 빌드 Pass해주시면 바로 실행가능합니다.

)* 클래스파일과 라이브러리파일 첨부해두었습니다.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory; import org.json.simple.JSONArray;import org.json.simple.JSONObject;import org.json.simple.JSONValue;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList; public class WeatherMain {     public static void main(String[] args) {        List<Map<String,Object>> list = getXml("대전 서구 관저동");        for(Map<String,Object> map : list){            System.out.println(map);        }    }            public static List<Map<String, Object>> getXml(String locate) {         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();                String location=locate;        String json="";        StringBuilder sb = new StringBuilder();        double v1 = 0.0;        double v2 = 0.0;        try {                        String addr = "http://maps.google.com/maps/api/geocode/json?address=";            URL url = new URL(addr + URLEncoder.encode(location, "UTF-8"));            HttpURLConnection con = (HttpURLConnection) url.openConnection();            con.setConnectTimeout(10000);            con.setUseCaches(false);            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));             while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            br.close();            con.disconnect();        } catch (Exception e) {            System.out.println(e.getMessage());        }        json = sb.toString();        JSONObject object = (JSONObject) JSONValue.parse(json);        JSONArray array = (JSONArray) object.get("results");        for (Object o : array) {            JSONObject object2 = (JSONObject) o;            String lat = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lat").toString();            String lng = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lng").toString();             v1 = Double.parseDouble(lat);            v2 = Double.parseDouble(lng);        }                //위에서 얻은 위도 경도를 가지고 GridX,GridY좌표를 구합니다.

        Map<String, Object> map = getGridxy(v1, v2);                String xml = "";        //GridX, GridY좌표를 가지고 XML데이터를 가져옵니다.

        try {            // 전국 날씨정보            String addr = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + map.get("x") + "&gridy=" + map.get("y");            URL url = new URL(addr);            HttpURLConnection http = (HttpURLConnection) url.openConnection();            http.setConnectTimeout(10000);            http.setUseCaches(false);             BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));            sb = new StringBuilder();            while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            xml = sb.toString();            br.close();            http.disconnect();         } catch (Exception e) {            System.out.println("다운로드에러" + e.getMessage());         }         Map<String, Object> data = new HashMap<String, Object>();        //위에서 추출한 XML데이터를 파싱해봅시다.

        try {            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder documentbuilder = factory.newDocumentBuilder();            InputStream is = new ByteArrayInputStream(xml.getBytes());            Document doc = documentbuilder.parse(is);            Element element = doc.getDocumentElement();             NodeList list1 = element.getElementsByTagName("data");             for (int i = 0; i < list1.getLength(); i++) {                for (Node node = list1.item(i).getFirstChild(); node != null; node = node.getNextSibling()) {                     if (node.getNodeName().equals("hour")) { //시간                        data = new HashMap<String, Object>();                        data.put("hour", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("temp")) { //온도                        data.put("temp", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("reh")) { //습도                        data.put("reh", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("wfEn")) { //날씨 정보                        data.put("wfEn", node.getTextContent().toString());                        list.add(data);                    }                }            }         } catch (Exception e) {            System.out.println("파싱에러" + e.getMessage());        }         return list;    }       public static Map<String, Object> getGridxy(double v1, double v2) {        double RE = 6371.00877; // 지구 반경(km)        double GRID = 5.0; // 격자 간격(km)        double SLAT1 = 30.0; // 투영 위도1(degree)        double SLAT2 = 60.0; // 투영 위도2(degree)        double OLON = 126.0; // 기준점 경도(degree)        double OLAT = 38.0; // 기준점 위도(degree)        double XO = 43; // 기준점 X좌표(GRID)        double YO = 136; // 기1준점 Y좌표(GRID)        double DEGRAD = Math.PI / 180.0;        // double RADDEG = 180.0 / Math.PI;         double re = RE / GRID;        double slat1 = SLAT1 * DEGRAD;        double slat2 = SLAT2 * DEGRAD;        double olon = OLON * DEGRAD;        double olat = OLAT * DEGRAD;         double 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);        double sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);        sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;        double ro = Math.tan(Math.PI * 0.25 + olat * 0.5);        ro = re * sf / Math.pow(ro, sn);        Map<String, Object> map = new HashMap<String, Object>();               double ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);        ra = re * sf / Math.pow(ra, sn);        double theta = v2 * DEGRAD - olon;        if (theta > Math.PI)            theta -= 2.0 * Math.PI;        if (theta < -Math.PI)            theta += 2.0 * Math.PI;        theta *= sn        map.put("lat", v1);       map.put("lng", v2);        map.put("x", (int)Math.floor(ra * Math.sin(theta) + XO + 0.5));        map.put("y", (int)Math.floor(ro - ra * Math.cos(theta) + YO + 0.5));         return map;    } } Colored by Color Scriptercs?최종 결과??좌표값으로 동네 주소 값얻기http://maps.google.com/maps/api/geocode/json?latlng=37,126maps.google.com  올여름 더위는 기억하는 여름 중 가장 덥고, 힘들었던 것 같습니다.

 특히 수도권 더위가 아주 심했죠. 해가 떠 있는 낮에도 덥지만, 해가 진 밤에도 낮처럼 높은 온도가 유지되면서,계속된 열대야에 몸과 마음이 모두 지치는 나날이었습니다.

  ‘얼마나 더웠는지’는 수치로도 확인할 수 있는데요, 열대야가 8월 들어 22일째 이어지고 있으며, 열대야가 나타나지 않은 날은 8월 2일 단 하루뿐이었습니다.

거의 한 달을 편안히 잠을 이룰 수 없었으니, 올여름이 더 힘들 수밖에 없었죠.  8월 폭염은 최근 40년 간 가장 더웠던 1994년과 비교해서 뒤지지 않을 정도로 뜨거웠습니다.

 서울은 8월 평균 최고 기온이 33.6도로 나타났는데, 이는 매일 같이 35도 안팎의 폭염이 이어진 셈입니다.

이 기록은 94년 평균이었던 33도보다 무려 1.6도가 높은 수치입니다.

또, 올해는 이례적으로 더위가 수그러들어야 할 8월 하순에 최고 기온이 기록되기도 했습니다.

 이처럼 8월 하순에 최고 기온이 나타난 것은 1945년 이후, 71년 만에 일어난 일이라고 합니다.

  올해는 우리나라 남쪽에 자리 잡은 더운 고기압의 세력이 강해서, 영향을 오랫동안 미쳤습니다.

 그런데 이 고기압이 비구름이 발달하는 것을 막고 있고, 우리나라 쪽으로 제대로 된 비구름이 다가서지 못해서 한 달가량 비조차 내리지 않는 날씨가 이어진 것입니다.

 비가 오지 않아 공기가 식지 못하고, 열이 계속 쌓이기만 하면서 기록적인 폭염이 이어졌습니다.

   여기서 가장 궁금한점은 도대체 왜? 기상청의 날씨 예측은 왜 자꾸 빗나갈까가 아닐까 싶네요. 미래의 날씨를 족집게처럼 맞추는 일이 쉽지 않다는 것은 다들 알지만, 그래도 많은 돈과 인력이 투입된 기상청의 역할이 중요한 시기에 예보가 틀려도 너무 자주 틀렸습니다.

[기상청 날씨정보] 할말이 없네요.


 올여름 초반 장맛비 예보는 아예 빗나갔고, 폭염이 끝난다는 지난주 금, 토요일에도 폭염이 이어졌습니다.

  이처럼 기상청 예보가 최근 자주 빗나가는 이유는 한반도를 둘러싼 공기의 움직임에 변화가 있기 때문이라고 합니다.

 일기예보는 기본적으로 자연의 이해를 바탕으로 하는데, 예전에 쌓아놓았던 경험적 자료들은 최근 달라진 환경과 잘 들어맞지 않습니다.

 즉, 한반도 기후 환경은 변화하고 있는데, 예보 법칙은 추세를 반영하지 못하므로, 예보가 자주 빗나갈 수밖에 없겠죠.   예전부터 컴퓨터나 IT에 관심이 많아 뉴스를 통해 기상청은 5백억 원이 넘는 슈퍼컴퓨터를 도입하였다고 들었습니다.

하지만 하드웨어만 좋아졌을뿐, 이 또한 예보의 정확성을 높이지는 못했습니다.

 슈퍼컴퓨터는 전 세계 인구가 1년 동안 계산할 양의 데이터를 불과 몇 초 만에 계산해 낼 수 있지만, 이 뛰어난 능력도 결국, 예보관들의 분석과 판단에 도움을 주는 것일 뿐입니다.

컴퓨터는 복잡한 미래의 날씨를 계산해낼 수는 있지만, 이를 분석하고, 설정한 수치 모델을 제시하는 것은 예보관의 역량에 달려있습니다.

  실제로 예보에 미치는 영향력을 따져 본 연구 결과, 슈퍼컴퓨터의 역할이 40% 수준인 것으로 나타나기도 했습니다.

그러니 슈퍼컴퓨터가 내놓은 데이터를 경험이 많은 예보관이 적절하게 분석하여야, 빗나가지 않는 일기예보를 할 수 있겠죠.   기상 관측 분야가 과거와 비교하면 많이 개선되기는 했지만, 우리나라 실정에 딱 맞는 수치 모델이 없는 상태이므로, 기상청은 오는 2019년까지 ‘한국형 수치 모델’을 개발할 계획이라고 합니다.

 하지만 무엇보다 중요한 것은 하루가 다르게 변하는 지구촌 기상환경을 효과적으로 연구할 수 있는 인력 또는 교육이나 연구방법을 확보하는 것이 중요할 것같습니다.

 )?제가 여러곳에서 기상청 데이터 파싱방법을 찾아본 결과 여러방법들이 존재하고 있었습니다.

대표적으로?1. 기상청에서 제공하는 동네코드를 알아낼 수 있는 url을 활용http://javaking75.blog.me/220091928699 [Java] ??? ???? ? ??? ?? ??? ????[??]???? (pluulove84) ??? - ??? ???? ??(?)?? : http://blog.naver.com/pluulove84/...blog.naver.com-> 단점 : 일부 지역은 포함하고있지 않아 모든 지역의 동네코드를 얻어올 수 없었습니다.

2. 기상청 RSS 활용http://www.kma.go.kr/weather/lifenindustry/sevice_rss.jspRSS > ??? > ??? > ??? ?? > ?? > ???www.kma.go.kr- 단점 : 동네 기상정보를 한 번에 한지역만 조회가가능 합니다.

3. 위도와 경도를 이용하여 GridX, GridY좌표 구해서 동네 예보가져오기 (가장  좋은 방법 같습니다.

[기상청 날씨정보] 분석을 해보면



)http://javaking75.blog.me/220089575454[JavaScript] ??? ???? ?? - ??? ( Grid XY - Lat, Lon ) : ?? ...???? http://www.kma.go.kr/weather/forecast/timeseries.jsp ???? ???? XML ??? ???...blog.naver.com* 이러한 방법들을 짬뽕하여 "지역 이름"을 하면 1. 구글 Geolocation 서비스를 이용하여 위도 경도 획득하고2. 위도, 경도를 기상청에서 만들어놓은 GridX, GridY를 구하는 공식을 이용하여 GridX,Y좌표를 구하여 동네주간예보를 가져오겠습니다.

시작!-1단계구글 Geolocation 서비스를 이용하여 "지역명"으로 위도(Longtitude),경도(Latitude) 가져오기*요청 URLhttp://maps.google.com/maps/api/geocode/json?address=지역이름ex) http://maps.google.com/maps/api/geocode/json?address=대전 서구 관저동아래처럼 크롬브라우저에다가 해당 url을 하게 되면이와 같이 JSON형태의 위치에 해당하는 정보들을 가져오게 됩니다.

여기서 필요한 정보는 location 의 "lat" , "lng" 의 정보입니다.

 * Json데이터를 손쉽게 추출하기위해서 아래 라이브러리를 사용하였습니다.

메이븐이나, 다운로드를 통해서 빌드시켜주세요http://www.mvnrepository.com/artifact/com.googlecode.json-simple/json-simple/1.1.1Maven Repository: com.googlecode.json-simple � json-simple � 1.1.1www.mvnrepository.com- lat, lng 좌표 가져오기1234567891011121314151617181920212223242526272829303132333435        String json;        StringBuilder sb = new StringBuilder();        double v1 = 0.0;        double v2 = 0.0;        try {            String location = "대전 서구 관저동";            String addr = "http://maps.google.com/maps/api/geocode/json?address=";            URL url = new URL(addr + URLEncoder.encode(location, "UTF-8"));            HttpURLConnection con = (HttpURLConnection) url.openConnection();            con.setConnectTimeout(10000);            con.setUseCaches(false);            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));             while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            br.close();            con.disconnect();        } catch (Exception e) {            System.out.println(e.getMessage());        }        json = sb.toString();        JSONObject object = (JSONObject) JSONValue.parse(json);        JSONArray array = (JSONArray) object.get("results");        for (Object o : array) {            JSONObject object2 = (JSONObject) o;            String lat = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lat").toString();            String lng = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lng").toString();             v1 = Double.parseDouble(lat);            v2 = Double.parseDouble(lng);        }Colored by Color Scriptercsv1, v2에 각각 위도와 경도를 저장하였습니다.

?2. 위도, 경도를 가지고 Gridx, Gridy 좌표 구하기위도 경도를 Gridx, Gridy좌표로 변경시켜주는 getGridxy함수의 매개변수에 이전에 얻어온 위도,경도(v1,v2)값을 넣으면됩니다.

 12345678910111213141516171819202122232425262728293031323334353637383940414243    double RE = 6371.00877; // 지구 반경(km)    double GRID = 5.0; // 격자 간격(km)    double SLAT1 = 30.0; // 투영 위도1(degree)    double SLAT2 = 60.0; // 투영 위도2(degree)    double OLON = 126.0; // 기준점 경도(degree)    double OLAT = 38.0; // 기준점 위도(degree)    double XO = 43; // 기준점 X좌표(GRID)    double YO = 136; // 기1준점 Y좌표(GRID)     public Map<String, Object> getGridxy(double v1, double v2) {         double DEGRAD = Math.PI / 180.0;        // double RADDEG = 180.0 / Math.PI;         double re = RE / GRID;        double slat1 = SLAT1 * DEGRAD;        double slat2 = SLAT2 * DEGRAD;        double olon = OLON * DEGRAD;        double olat = OLAT * DEGRAD;         double 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);        double sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);        sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;        double ro = Math.tan(Math.PI * 0.25 + olat * 0.5);        ro = re * sf / Math.pow(ro, sn);        Map<String, Object> map = new HashMap<String, Object>();        map.put("lat", v1);        map.put("lng", v1);        double ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);        ra = re * sf / Math.pow(ra, sn);        double theta = v2 * DEGRAD - olon;        if (theta > Math.PI)            theta -= 2.0 * Math.PI;        if (theta < -Math.PI)            theta += 2.0 * Math.PI;        theta *= sn;         map.put("x", Math.floor(ra * Math.sin(theta) + XO + 0.5));        map.put("y", Math.floor(ro - ra * Math.cos(theta) + YO + 0.5));         return map;    }Colored by Color Scriptercs?* Map형태로 "x", "y"키 값에 각각 Gridx, Gridy값을 저장하였습니다.

 3. 위에서 얻은 Gridx,Gridy 값으로 동네 xml데이터 얻기* 요청 urlhttp://www.kma.go.kr/wid/queryDFS.jsp?gridx=x좌표&gridy=y좌표ex) http://www.kma.go.kr/wid/queryDFS.jsp?gridx=66gridy=99 (대전 서구 관저동 날씨)아래와 같은 xml데이터를 리턴합니다.

- 동네 예보 xml 태그 설명서http://www.kma.go.kr/images/weather/lifenindustry/timeseries_XML.pdf123456789101112131415161718192021222324String xml = "";        try {            // 전국 날씨정보            String addr = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + map.get("x") + "&gridy=" + map.get("y");            URL url = new URL(addr);            HttpURLConnection http = (HttpURLConnection) url.openConnection();            http.setConnectTimeout(10000);            http.setUseCaches(false);             BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));            sb = new StringBuilder();            while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            xml = sb.toString();            br.close();            http.disconnect();         } catch (Exception e) {            System.out.println("다운로드에러" + e.getMessage());        }Colored by Color Scriptercs4. XML기상 정보 파싱1234567891011121314151617181920212223242526272829303132333435363738        Map<String, Object> data = new HashMap<String, Object>();        try {            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder documentbuilder = factory.newDocumentBuilder();            InputStream is = new ByteArrayInputStream(xml.getBytes());            Document doc = documentbuilder.parse(is);            Element element = doc.getDocumentElement();             NodeList list1 = element.getElementsByTagName("data");             for (int i = 0; i < list1.getLength(); i++) {                for (Node node = list1.item(i).getFirstChild(); node != null; node = node.getNextSibling()) {                     if (node.getNodeName().equals("hour")) {                        System.out.println("----------------------------");                        data = new HashMap<String, Object>();                        data.put("hour", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("temp")) {                        data.put("temp", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("reh")) {                        data.put("reh", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("wfEn")) {                        data.put("wfEn", node.getTextContent().toString());                        list.add(data);                    }                }            }         } catch (Exception e) {            System.out.println("파싱에러" + e.getMessage());        }        System.out.println(data);Colored by Color Scriptercs*결과?전체코드 (*JSON라이브러리만 빌드 Pass해주시면 바로 실행가능합니다.

)* 클래스파일과 라이브러리파일 첨부해두었습니다.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory; import org.json.simple.JSONArray;import org.json.simple.JSONObject;import org.json.simple.JSONValue;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList; public class WeatherMain {     public static void main(String[] args) {        List<Map<String,Object>> list = getXml("대전 서구 관저동");        for(Map<String,Object> map : list){            System.out.println(map);        }    }            public static List<Map<String, Object>> getXml(String locate) {         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();                String location=locate;        String json="";        StringBuilder sb = new StringBuilder();        double v1 = 0.0;        double v2 = 0.0;        try {                        String addr = "http://maps.google.com/maps/api/geocode/json?address=";            URL url = new URL(addr + URLEncoder.encode(location, "UTF-8"));            HttpURLConnection con = (HttpURLConnection) url.openConnection();            con.setConnectTimeout(10000);            con.setUseCaches(false);            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));             while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            br.close();            con.disconnect();        } catch (Exception e) {            System.out.println(e.getMessage());        }        json = sb.toString();        JSONObject object = (JSONObject) JSONValue.parse(json);        JSONArray array = (JSONArray) object.get("results");        for (Object o : array) {            JSONObject object2 = (JSONObject) o;            String lat = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lat").toString();            String lng = ((JSONObject) (((JSONObject) object2.get("geometry")).get("location"))).get("lng").toString();             v1 = Double.parseDouble(lat);            v2 = Double.parseDouble(lng);        }                //위에서 얻은 위도 경도를 가지고 GridX,GridY좌표를 구합니다.

        Map<String, Object> map = getGridxy(v1, v2);                String xml = "";        //GridX, GridY좌표를 가지고 XML데이터를 가져옵니다.

        try {            // 전국 날씨정보            String addr = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=" + map.get("x") + "&gridy=" + map.get("y");            URL url = new URL(addr);            HttpURLConnection http = (HttpURLConnection) url.openConnection();            http.setConnectTimeout(10000);            http.setUseCaches(false);             BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));            sb = new StringBuilder();            while (true) {                String line = br.readLine();                if (line == null)                    break;                sb.append(line);            }            xml = sb.toString();            br.close();            http.disconnect();         } catch (Exception e) {            System.out.println("다운로드에러" + e.getMessage());         }         Map<String, Object> data = new HashMap<String, Object>();        //위에서 추출한 XML데이터를 파싱해봅시다.

        try {            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder documentbuilder = factory.newDocumentBuilder();            InputStream is = new ByteArrayInputStream(xml.getBytes());            Document doc = documentbuilder.parse(is);            Element element = doc.getDocumentElement();             NodeList list1 = element.getElementsByTagName("data");             for (int i = 0; i < list1.getLength(); i++) {                for (Node node = list1.item(i).getFirstChild(); node != null; node = node.getNextSibling()) {                     if (node.getNodeName().equals("hour")) { //시간                        data = new HashMap<String, Object>();                        data.put("hour", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("temp")) { //온도                        data.put("temp", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("reh")) { //습도                        data.put("reh", node.getTextContent().toString());                    }                     if (node.getNodeName().equals("wfEn")) { //날씨 정보                        data.put("wfEn", node.getTextContent().toString());                        list.add(data);                    }                }            }         } catch (Exception e) {            System.out.println("파싱에러" + e.getMessage());        }         return list;    }       public static Map<String, Object> getGridxy(double v1, double v2) {        double RE = 6371.00877; // 지구 반경(km)        double GRID = 5.0; // 격자 간격(km)        double SLAT1 = 30.0; // 투영 위도1(degree)        double SLAT2 = 60.0; // 투영 위도2(degree)        double OLON = 126.0; // 기준점 경도(degree)        double OLAT = 38.0; // 기준점 위도(degree)        double XO = 43; // 기준점 X좌표(GRID)        double YO = 136; // 기1준점 Y좌표(GRID)        double DEGRAD = Math.PI / 180.0;        // double RADDEG = 180.0 / Math.PI;         double re = RE / GRID;        double slat1 = SLAT1 * DEGRAD;        double slat2 = SLAT2 * DEGRAD;        double olon = OLON * DEGRAD;        double olat = OLAT * DEGRAD;         double 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);        double sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);        sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;        double ro = Math.tan(Math.PI * 0.25 + olat * 0.5);        ro = re * sf / Math.pow(ro, sn);        Map<String, Object> map = new HashMap<String, Object>();               double ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);        ra = re * sf / Math.pow(ra, sn);        double theta = v2 * DEGRAD - olon;        if (theta > Math.PI)            theta -= 2.0 * Math.PI;        if (theta < -Math.PI)            theta += 2.0 * Math.PI;        theta *= sn        map.put("lat", v1);       map.put("lng", v2);        map.put("x", (int)Math.floor(ra * Math.sin(theta) + XO + 0.5));        map.put("y", (int)Math.floor(ro - ra * Math.cos(theta) + YO + 0.5));         return map;    } } Colored by Color Scriptercs?최종 결과??좌표값으로 동네 주소 값얻기http://maps.google.com/maps/api/geocode/json?latlng=37,126maps.google.com  올여름 더위는 기억하는 여름 중 가장 덥고, 힘들었던 것 같습니다.

 특히 수도권 더위가 아주 심했죠. 해가 떠 있는 낮에도 덥지만, 해가 진 밤에도 낮처럼 높은 온도가 유지되면서,계속된 열대야에 몸과 마음이 모두 지치는 나날이었습니다.

  ‘얼마나 더웠는지’는 수치로도 확인할 수 있는데요, 열대야가 8월 들어 22일째 이어지고 있으며, 열대야가 나타나지 않은 날은 8월 2일 단 하루뿐이었습니다.

거의 한 달을 편안히 잠을 이룰 수 없었으니, 올여름이 더 힘들 수밖에 없었죠.  8월 폭염은 최근 40년 간 가장 더웠던 1994년과 비교해서 뒤지지 않을 정도로 뜨거웠습니다.

 서울은 8월 평균 최고 기온이 33.6도로 나타났는데, 이는 매일 같이 35도 안팎의 폭염이 이어진 셈입니다.

이 기록은 94년 평균이었던 33도보다 무려 1.6도가 높은 수치입니다.

또, 올해는 이례적으로 더위가 수그러들어야 할 8월 하순에 최고 기온이 기록되기도 했습니다.

 이처럼 8월 하순에 최고 기온이 나타난 것은 1945년 이후, 71년 만에 일어난 일이라고 합니다.

  올해는 우리나라 남쪽에 자리 잡은 더운 고기압의 세력이 강해서, 영향을 오랫동안 미쳤습니다.

 그런데 이 고기압이 비구름이 발달하는 것을 막고 있고, 우리나라 쪽으로 제대로 된 비구름이 다가서지 못해서 한 달가량 비조차 내리지 않는 날씨가 이어진 것입니다.

 비가 오지 않아 공기가 식지 못하고, 열이 계속 쌓이기만 하면서 기록적인 폭염이 이어졌습니다.

   여기서 가장 궁금한점은 도대체 왜? 기상청의 날씨 예측은 왜 자꾸 빗나갈까가 아닐까 싶네요. 미래의 날씨를 족집게처럼 맞추는 일이 쉽지 않다는 것은 다들 알지만, 그래도 많은 돈과 인력이 투입된 기상청의 역할이 중요한 시기에 예보가 틀려도 너무 자주 틀렸습니다.

 올여름 초반 장맛비 예보는 아예 빗나갔고, 폭염이 끝난다는 지난주 금, 토요일에도 폭염이 이어졌습니다.

  이처럼 기상청 예보가 최근 자주 빗나가는 이유는 한반도를 둘러싼 공기의 움직임에 변화가 있기 때문이라고 합니다.

 일기예보는 기본적으로 자연의 이해를 바탕으로 하는데, 예전에 쌓아놓았던 경험적 자료들은 최근 달라진 환경과 잘 들어맞지 않습니다.

 즉, 한반도 기후 환경은 변화하고 있는데, 예보 법칙은 추세를 반영하지 못하므로, 예보가 자주 빗나갈 수밖에 없겠죠.   예전부터 컴퓨터나 IT에 관심이 많아 뉴스를 통해 기상청은 5백억 원이 넘는 슈퍼컴퓨터를 도입하였다고 들었습니다.

하지만 하드웨어만 좋아졌을뿐, 이 또한 예보의 정확성을 높이지는 못했습니다.

 슈퍼컴퓨터는 전 세계 인구가 1년 동안 계산할 양의 데이터를 불과 몇 초 만에 계산해 낼 수 있지만, 이 뛰어난 능력도 결국, 예보관들의 분석과 판단에 도움을 주는 것일 뿐입니다.

컴퓨터는 복잡한 미래의 날씨를 계산해낼 수는 있지만, 이를 분석하고, 설정한 수치 모델을 제시하는 것은 예보관의 역량에 달려있습니다.

  실제로 예보에 미치는 영향력을 따져 본 연구 결과, 슈퍼컴퓨터의 역할이 40% 수준인 것으로 나타나기도 했습니다.

그러니 슈퍼컴퓨터가 내놓은 데이터를 경험이 많은 예보관이 적절하게 분석하여야, 빗나가지 않는 일기예보를 할 수 있겠죠.   기상 관측 분야가 과거와 비교하면 많이 개선되기는 했지만, 우리나라 실정에 딱 맞는 수치 모델이 없는 상태이므로, 기상청은 오는 2019년까지 ‘한국형 수치 모델’을 개발할 계획이라고 합니다.

 하지만 무엇보다 중요한 것은 하루가 다르게 변하는 지구촌 기상환경을 효과적으로 연구할 수 있는 인력 또는 교육이나 연구방법을 확보하는 것이 중요할 것같습니다.

 16 개봉 | 12세이상관람가 | 125분감독 : 이준익출연 : 송강호, 유아인, 문근영, 전혜진, 등1762년(영조 38년) 임오년, 아버지 영조에 의해 뒤주에 갇힌 사도세자의 슬픈 이야기.(역사책에서는 임오화변(壬午禍變)이라고 한다.

)보기전에 미리 역사적 배경이나 사실을 알아두면 영화를 더 재미있게 볼 수 있을것 같다.

(영조의 왕위등극 배경, 영조와 노론, 영정조 가계도, 등)초반부에 약간 지루감도 있지만 스토리가 진행될수록 점점 빠져드는 느낌이 든다그러다 영화가 끝이나면 여운이 크게 남는다.

(천륜지간(天倫之間)이라는 부자(父子)의 인연도 왕과 세자라는 신분앞에서는 어쩔 수 없는것인가...정말 마음 아픈 이야기다.

).....PS...송강호(영조 분) 유아인(사도세자 분)의 연기 정말 좋았다.

 날짜 : 2016년 7월 6일 수요일  오전 : 흐림  기온 23℃  강수확률  20% 오후 : 흐리고 가끔 비  기온 30℃  강수확률  60% 
공유하기 링크
TAG
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
댓글
댓글쓰기 폼