공공 데이터에서 얻어온 주소를 카카오맵 마커 표시를 위해 좌표로 변환해야한다!
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 형으로 변환해서 원하는 곳에 입맛에 따라 사용하면 된다.
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)
}
를 넣어주면 해결된다.
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이 발생한다.