카카오 Rest API로 주소 좌표 변환하기

Kim Nahyeong·2021년 11월 22일
0
post-thumbnail

문제

공공 데이터에서 얻어온 주소를 카카오맵 마커 표시를 위해 좌표로 변환해야한다!

필요한 것 :

kakao developers에서 앱 등록하고 얻은 REST API 키
(기본 앱 등록에 사용했던 네이티브 앱 키와는 다르다)

해결 방법

private val GEOCODE_URL : String ="http://dapi.kakao.com/v2/local/search/address.json?query="
private val GEOCODE_USER_INFO : String ="(REST API key)"

API에 필요한 정보를 변수로 지정해 관리해준다.
괄호 안에 자신의 키를 복사해 넣어주면 된다.

private fun getGeoCode() {
        System.out.println("getting GeoCode")
        val obj : URL
        try{
            val address : String = URLEncoder.encode("대구광역시 중구 동성로2가 동성로2길 81", "UTF-8")

            obj = URL(GEOCODE_URL+address)

            val con : HttpURLConnection = obj.openConnection() as HttpURLConnection

            con.setRequestMethod("GET")
            con.setRequestProperty("Authorization", "KakaoAK " + GEOCODE_USER_INFO)
            con.setRequestProperty("content-type", "application/json")
            con.setDoOutput(true)
            con.setUseCaches(false)
            con.setDefaultUseCaches(false)

            val data = con.inputStream.bufferedReader().readText()
            val dataList = "[$data]"
            val xy = Gson().fromJson(dataList, Array<Address>::class.java).toList()
            for(i in 0..xy.size-1){
                System.out.println("x: ${xy[i].documents[i].address.x}, y: ${xy[i].documents[i].address.y}")
            }
            
            //System.out.println(data) // 얻은 객체 출력
        } catch (e : Exception) {
            e.printStackTrace()
        }
    }

를 넣고 필요한 부분에 함수를 호출해주면 된다. parameter에 주소 String을 받아서 처리하면 좋을텐데 아직 거기까지는 작업을 안했다. 된다는 것 까지만 확인했을 뿐...
추후 작업할 예정

결과

{
    "documents": [
        {
            "address": {
                "address_name": "대구 중구 동성로2가 70-1",
                "b_code": "2711012300",
                "h_code": "2711056500",
                "main_address_no": "70",
                "mountain_yn": "N",
                "region_1depth_name": "대구",
                "region_2depth_name": "중구",
                "region_3depth_h_name": "성내1동",
                "region_3depth_name": "동성로2가",
                "sub_address_no": "1",
                "x": "128.596965097921",
                "y": "35.86954385295"
            },
            "address_name": "대구 중구 동성로2길 81",
            "address_type": "ROAD_ADDR",
            "road_address": {
                "address_name": "대구 중구 동성로2길 81",
                "building_name": "",
                "main_building_no": "81",
                "region_1depth_name": "대구",
                "region_2depth_name": "중구",
                "region_3depth_name": "동성로2가",
                "road_name": "동성로2길",
                "sub_building_no": "",
                "underground_yn": "N",
                "x": "128.596965097921",
                "y": "35.86954385295",
                "zone_no": "41938"
            },
            "x": "128.596965097921",
            "y": "35.86954385295"
        }
    ],
    "meta": {
        "is_end": true,
        "pageable_count": 1,
        "total_count": 1
    }
}

이런 json 형태의 String이 data에 담겨 출력된다.
Gson으로 String을 json으로 파싱을 해 x와 y좌표를 알아내면 된다.

작업해서 추가시켰다.
해결 방법의 코드에서 Address는 json을 넣을 DTO 클래스다. 그냥 Postman에 나온 결과를 Kotlin data class file from Json 플러그인을 이용해서 변환했다. 귀찮... 남이 만들어 둔 것을 잘 활용하자.

좌표는 이렇게 출력된다. 이제 double 형으로 변환해서 원하는 곳에 입맛에 따라 사용하면 된다.

에러 해결

1.

W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1668)
W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)

이런 에러 발생시,

setContentView(R.layout.activity_main)
if (Build.VERSION.SDK_INT > 9) {
     val policy = ThreadPolicy.Builder().permitAll().build()
     StrictMode.setThreadPolicy(policy)
}

를 넣어주면 해결된다.

2.

java.io.FileNotFoundException: http://dapi.kakao.com/v2/local/search/address.json?query=%

이런 말이 뜨는데 이건 404 에러가 났다는 의미이다.
URL 클릭시

{"errorType":"AccessDeniedError", "message":"cannot find Authorization : KakaoAk header"}

이런 메세지가 뜨는 창을 확인할 수 있는데 그 해결법은 바로

그렇다고 한다. 위 해결 코드는

con.setRequestProperty("Authorization", "KakaoAK " + GEOCODE_USER_INFO)

라고 이미 넣어줘서 아마 에러가 나지 않을 것이다.
참고 코드와 다르게 앞에 KakaoAK 이것만 넣어주면 된다.

Postman에

이런식으로 넣어서 값이 출력되는지 확인하는 게 좋을 것이다. 안나오면 잘못된 request이기에 404가 뜨면서 FileNotFoundException이 발생한다.

참고 자료

JH_dev님 블로그
코집사님 블로그
Sun9님 블로그

0개의 댓글