Geocoding API

지번, 도로명을 질의어로 사용해서 주소를 검색하여 주소 목록과 세부 정보에 대한 검색 결과를 json 형태로 반환하는 서비스를 제공합니다.

1. 먼저 Client ID, Secret의 값이 필요합니다.

Naver Cloud Platform 콘솔에서 애플리케이션을 등록해 발급받습니다.

 

네이버에서 제공하는 Geocoding 공식문서를 토대로 작성하였습니다.

 

 

Geocoding 개요 - Geocoding

 

api.ncloud-docs.com

 

2. 회원가입과 서비스 신청 후 Postman를 통해 테스팅 해보겠습니다.

Postman : API 개발, 테스트가 가능한 GUI 툴

 

 

요청 URL, 요청 파라미터, 요청 헤더

값을 얻기위해 필수로 필요한 값으로만 주소를 검색하고

위도 경도를 추출해보겠습니다.

 

 

BaseURL : https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode

필수 요청 헤더 : X-NCP-APIGW-API-KEY-ID, X-NCP-APIGW-API-KEY

필수 요청 파라미터 : query 즉, 원하는 주소 입력 → 서울시

 

보시는 거와 같이 도로명주소, 지번주소, 영문주소, 위도 경도

정상적으로 출력 되는 것을 볼 수 있습니다.

제가 원하는 건 주소를 검색 했을 시 X, Y(경도 위도)기 때문에

Kotlin에서 검색 할 시 특정 주소에 경도와 위도만 출력 해보겠습니다.

 

 

 

레트로핏2 라이브러리 의존성 추가, 인터넷 권한을 추가해야합니다.

 

dependencies {
    implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
    implementation 'com.squareup.retrofit2:retrofit:2.6.0'
}
   <uses-permission android:name="android.permission.INTERNET"/>

 

Retrofit2

API의 값을 가져오기 위해선 HTTP를 통신해야하고

통신을 원할하게 하는 라이브러리입니다.

코드 작성 GeocodeAPI.kt

 

package com.project.navergeocoding.gecodeapi

import com.project.navergeocoding.GeocodeDTO
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query

interface GeocodeAPI {
    @GET("/map-geocode/v2/geocode") //Base url을 제외한 주소
    fun getAddress(
        @Query("query") query: String, //사용자가 입력할 주소, 요청 파라미터 필수여부 Y
        @Header("X-NCP-APIGW-API-KEY-ID") clientId: String, //필수 요청 헤더값 ID, API KEY
        @Header("X-NCP-APIGW-API-KEY") clientSecret: String //요청 헤더 필수여부 Y
    ): Call<Geocode> //반환형은 모델 데이터
}

 

GeoCode.kt

package com.project.navergeocoding
//실제로 출력해야 할 값을 지정하는 Data class
import com.google.gson.annotations.SerializedName

data class Geocode(
    //@SerializedName Postman의 결과 파라미터 값을 매칭
    //응답 바디
    @SerializedName("status")val status: String, //검색 결과 상태 코드, 필수여부 Y
    // 응답 버디 중 원하는 값 출력, 필수여부 N, "addresses" : 내부에 x, y가 있기 때문에 DTO 생성
   //전체 데이터를 가져오는 것이 아닌 addresses의 값을 가져오기 때문에 DTO 생성
    @SerializedName("addresses")val addresses: Array<AddressesDTO>

)

 

 

 

AddressesDTO.kt

package com.project.navergeocoding

import com.google.gson.annotations.SerializedName
//addresses 내부에 있는 도로명 주소, 위도, 영문 주소 등 추출하는 공간

data class AddressesDTO(
    @SerializedName("x")val x: String, //경도
    @SerializedName("y")val y: String,  //위도
)

 

 

MainActivity.kt

package com.project.navergeocoding

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import com.project.navergeocoding.gecodeapi.GeocodeAPI
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class MainActivity : AppCompatActivity() {

    private val address_Result: TextView by lazy {
        findViewById(R.id.address_Result)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //빌더 패턴을 통해 baseUrl과 json 변환 추가
        val retrofit = Retrofit.Builder()
            .baseUrl("https://naveropenapi.apigw.ntruss.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        //인터페이스 구현을 위한 변수 geocodeAPI
        val gecodeAPI = retrofit.create(GeocodeAPI::class.java)
        //인터페이스 내부에 있는 함수에 쿼리, 헤더를 입력함
        gecodeAPI.getAddress("TODO 원하는 주소 입력","TODO 클라이언트 ID 값","TODO 클라이언트 API 값")
            .enqueue(object: Callback<Geocode> {
                override fun onResponse(call: Call<Geocode>, response: Response<Geocode>) {
                    //실패 시 리턴
                    if(response.isSuccessful.not()) {
                        return
                    }
                    //response 즉, 결과 값이 널이 아니라면 출력
                    response.body()?.let {
                        it.addresses.forEach {
                            Log.d("TAG", it.toString())
                            address_Result.text = it.toString()
                        }
                }
                override fun onFailure(call: Call<Geocode>, t: Throwable) {
                    Log.d("TAG", "실패")
                }

            })
    }
}

 

 

결과

 

query의 서울시를 입력하여 서울시의 경도와 위도를 출력하였습니다.

저는 웹을 호스팅하여 개별 서버를 만든 후 카카오 주소 검색 API의 주소 값을

query의 파라미터로 넘긴 후 도로명 주소, 경도, 위도를 DB에 저장하여 Map의 마커를 구현할 예정입니다.

 

결과

 

 

Firebase Hosting을 통해 개인 서버를 만들고 카카오 주소 API를 통해

주소검색을 한 후 주소검색한 값을 query에 기입하였습니다.

코드 작성시 it 즉, addresses 내부의 값만 출력하고 싶다면 it.변수

 

response.body()?.let {
    it.addresses.forEach {
    x_Result.text = it.x.toString()
    y_Result.text = it.y.toString()
    Log.d("결과", "결과는 ${it}")
    }
}
복사했습니다!