본문 바로가기
Java

[Java] Kakao map 카카오맵 로컬 API 좌표(경도, 위도)로 주소 변환하기(REST API)

by 애리몽 2021. 9. 2.
반응형

안녕하세요 애리몽입니다.

오늘은 좌표를 이용하여 주소를 가져오는 카카오맵 로컬 API를 사용하면서 삽질했던 부분들 정리 해보려고 합니다.

좌표-주소 변환 특정 좌표의 지번 주소 및 도로명 주소 제공

제가 필요했던 기능은 경도, 위도를 주소로 변환하는 기능이었구요. 아래 두 문서와 여러 블로그를 참고해서 만들었습니다. 로컬 API는 REST API 방식으로만 이용할 수 있다고 해서 REST API방식을 사용하였습니다.

https://developers.kakao.com/docs/latest/ko/local/common

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

https://developers.kakao.com/docs/latest/ko/local/dev-guide#coord-to-address

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

크게 세 단계를 통해 주소를 가져왔습니다.

1. 카카오 개발자 사이트에서 도메인, 아이피 설정
2. 클라이언트 사이드(JSP)에서 자바스크립트(Javascript)를 이용해서 경,위도 정보 받아오기
3. 서버 사이드(Controller.java)에서 REST API로 주소 받아서 처리

1번에서 조금 헤맸는데 2, 3번은 금방 할 수 있어요!

 

1. 카카오 개발자 사이트에서 도메인, 아이피 설정

1-1. 카카오 개발자 사이트(https://developers.kakao.com/)에 접속해서 [내 애플리케이션 > 애플리케이션 추가하기] 로 웹사이트 정보 추가

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

 

1-2.  [내 애플리케이션 > 앱 설정 > 앱 키]에서 REST API 키 가져오기 

 

 

1-3.  [내 애플리케이션 > 고급 설정 > 허용 IP 주소]에 내 아이피 추가

REST API 키 혹은 Admin 키로 API를 호출할 경우에는 꼭 허용 서버 IP주소를 지정해야 호출이 가능한데요.

외부에서 접근 해야하기 때문에 외부(공인) 아이피를 추가 해야해요.

127.0.01 이나 내부에서 사용중인 IP (Ex 192.168.xxx.xxx) 를 지정하면 안 됩니다!

 

 

 

2. 클라이언트 사이드(JSP)에서 자바스크립트를 이용해서 경,위도 정보 받아오기

// 위치정보 사용
function getLocation() {
	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(getAddressByCoords,redirectLocation, geo_options);
        //navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{ timeout: 10_000 });
	} else {
		location.href = "/mbl/test/selectAddressList.do";
	}
}

//성공했을 때
function getAddressByCoords(position) {
	var longitude = position.coords.longitude;
	var latitude = position.coords.latitude;
	console.log(longitude);
    console.log(latitude);
    //★★위도 경도 정보를 가지고 서버 사이드로 넘어가는 부분
	location.href = "/mbl/test/selectAddressList.do?longitude=" + longitude + "&latitude=" + latitude;
}

//에러났을 때
function redirectLocation(error) {
	location.href = "/mbl/error/selectAddressList.do";
}

//타임아웃
var geo_options = {
	maximumAge        : 5000, 
	timeout           : 3000
};

클라이언트 사이드에서 자바스크립트로 경도와 위도의 정보를 받아서 컨트롤러로 넘겨줍니다. 

Geolocation API를 이용해서 현재 위치(position)를 받아와서 좌표를 얻었고, longtitude는 경도 latitude는 위도입니다.

Geolocation API에 대해 더 알아보실 분은 아래 문서 참고해주세요~!

https://www.w3schools.com/jsref/api_geolocation.asp

 

Geolocation Object

The Geolocation Object Geolocation Object The Geolocation object allows the user to provide their location to web applications. For privacy reasons, the user is asked for permission to report location information. Note: This feature is available only in se

www.w3schools.com

 

 

 

3. 서버 사이드(Controller.java)에서 REST API로 주소 받아서 처리

    /**
      * 경위도 정보로 주소를 불러오는 메소드
      * @throws UnsupportedEncodingException 
      */
      public static String coordToAddr(String longitude, String latitude){
        String url = "https://dapi.kakao.com/v2/local/geo/coord2address.json?x="+longitude+"&y="+latitude;
        String addr = "";
        try{
          addr = getRegionAddress(getJSONData(url));
          //LOGGER.info(addr);
        }catch(Exception e){
          System.out.println("주소 api 요청 에러");
          e.printStackTrace();
        }
          return addr;
      }

    /**
      * REST API로 통신하여 받은 JSON형태의 데이터를 String으로 받아오는 메소드
      */
	private static String getJSONData(String apiUrl) throws Exception {
    	HttpURLConnection conn = null;
    	StringBuffer response = new StringBuffer();
    	 
    	//인증키 - KakaoAK하고 한 칸 띄워주셔야해요!
    	String auth = "KakaoAK " + "★REST API 키★";

    	//URL 설정
        URL url = new URL(apiUrl);
         
        conn = (HttpURLConnection) url.openConnection();
        
        //Request 형식 설정
        conn.setRequestMethod("GET");
        conn.setRequestProperty("X-Requested-With", "curl");
        conn.setRequestProperty("Authorization", auth);

        //request에 JSON data 준비
        conn.setDoOutput(true);
         
        //보내고 결과값 받기
        int responseCode = conn.getResponseCode();
        if (responseCode == 400) {
            System.out.println("400:: 해당 명령을 실행할 수 없음");
        } else if (responseCode == 401) {
            System.out.println("401:: Authorization가 잘못됨");
        } else if (responseCode == 500) {
            System.out.println("500:: 서버 에러, 문의 필요");
        } else { // 성공 후 응답 JSON 데이터받기
        	 
        	 Charset charset = Charset.forName("UTF-8");
             BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
             
             String inputLine;
             while ((inputLine = br.readLine()) != null) {
             	response.append(inputLine); 
             } 
         }
         
         return response.toString();
    }
    
     /**
      * JSON형태의 String 데이터에서 주소값(address_name)만 받아오기
      */
	private static String getRegionAddress(String jsonString) {
        String value = "";
        JSONObject jObj = (JSONObject) JSONValue.parse(jsonString);
        JSONObject meta = (JSONObject) jObj.get("meta");
        long size = (long) meta.get("total_count");
        
        if(size>0){
            JSONArray jArray = (JSONArray) jObj.get("documents");
            JSONObject subJobj = (JSONObject) jArray.get(0);
            JSONObject roadAddress =  (JSONObject) subJobj.get("road_address");
            
            if(roadAddress == null){
                JSONObject subsubJobj = (JSONObject) subJobj.get("address");
                value = (String) subsubJobj.get("address_name");
            }else{
                value = (String) roadAddress.get("address_name");
            }
            
            if(value.equals("") || value==null){
                subJobj = (JSONObject) jArray.get(1);
                subJobj = (JSONObject) subJobj.get("address");
                value =(String) subJobj.get("address_name");    
            }
        }
        return value;
    }

 

이렇게 하면 경도와 위도로 주소를 불러올 수 있습니다~!~!

주소 가져와서 필요대로 비즈니스 로직 짜서 사용하면 되겠죠~?

전 위치기반 검색 기능을 구현했습니다ㅎㅎ 모바일에서 주로 사용하는 기능인데요.

주변에 맛집 찾을 때 맛집 주소 리스트만 있으면 유용하게 쓰겠다는 생각이 갑자기 드네요. 배고픈가봐요...

이만 포스팅을 마치겠습니다!

 

※ 결과값이 안 나올 때 -> {"meta":{"total_count":0},"documents":[]}

거의 다 했는데 결과값이 안 나오는 거에요.... 아무리 봐도 어디가 틀린지 모르겠고..

로그를 찍어봐도 {"meta":{"total_count":0},"documents":[]} 데이터가 없다고 뜨고.... 검색해봐도 잘 안 나오고ㅜㅜ

문서를 멍하니 보다가 원인을 알아냈어요! 결국 답은 공식 문서에서 찾나봐요.

경도, 위도  순서 주의!!!!!!!

우리가 보통 위경도 이렇게 말을 많이 하잖아요. 구글맵에서 좌표로 검색할때도 위도, 경도 순으로 검색하고

하지만 카카오맵 좌표로 주소 검색시 x=경도, y=위도로 파라미터를 넘겨줘야 한답니다^^ 휴

https://dapi.kakao.com/v2/local/geo/coord2address.json?x=경도&y=위도

 

좋은 하루 되세요~!!!!

반응형