본문 바로가기

Backend/외부 API

구글 Geocoding API 사용해서 위도 경도 검색하기

0) 서론

현재 진행 중인 프로젝트에서 위도와 경도를 기반으로 주소를 검색하는 API를 연동하는 작업을 담당하게 되었다.

프로젝트 요구사항에 따라 엔티티에 반드시 위도와 경도 정보가 포함되어야 하는데,  사람이 직접 주소를 기반으로 위도와 경도를 일일이 변환하여 입력하는 작업은 비효율적이고 번거롭다.

 

이 문제를 해결하기 위해 방법을 찾아보다가 주소를 위도와 경도로 변환해주는 Google Geocoding API 를 알게되었다.

먼저 API Key부터 발급받아야한다.

1) API Key 발급 받기

일단 Google Cloud에 접속해 프로젝트를 생성해야한다. 새 프로젝트를 눌러 프로젝트를 생성하자. 

 

그럼 결제 정보를 입력하는 화면으로 이동하고, 정보를 모두 입력하고 나면 API 키를 발급해준다. 

이 키는 외부로 노출하면 안되기 때문에 프로젝트에서 사용할 때 환경변수로 숨기거나 다른 방법을 사용해 숨겨줘야한다.

ex) application.yml 에 설정하는 법

google:
  maps:
    api:
      key: ${GOOGLE_API_KEY}

2) 프로젝트 환경 설정하기

그리고 역시 build.gradle 의존성을 추가해야한다. 최신 버전을 사용해야 한다.

// 2024년 12월 11일 기준 최신 버전 
implementation group: 'com.google.maps', name: 'google-maps-services', version: '2.2.0'

3) Service와 Response 정의하기

다음으로는 Service를 정의하자.

전체적인 코드는 https://dkan9634.tistory.com/176 블로그를 참고했다.

@Service
public class GeocodingService {

  private String googleMapsApiKey;

  @Value("${google.maps.api.key}")
  public void SetGoogleMapsApiKey(String googleMapsApiKey) {
    this.googleMapsApiKey = googleMapsApiKey;
  }

  public AddressResponse getLatLngByAddress(String address)
      throws IOException, InterruptedException, ApiException {
    String entireAddress = "대한민국 " + address;
    GeoApiContext context = new GeoApiContext.Builder()
        .apiKey(googleMapsApiKey)
        .build();
    GeocodingResult[] results = GeocodingApi.geocode(context, entireAddress)
        .region("kr")
        .await();
    if (results.length > 0) {
      GeocodingResult result = results[0];
      double latitude = result.geometry.location.lat;
      double longitude = result.geometry.location.lng;
      return new AddressResponse(latitude, longitude);
    } else {
      return null;
    }
  }
}

 

간단하게 코드 설명을 남기자면,

- 먼저 @Value("${google.maps.api.key}")를 사용해 application.yml 에 정의된 API 키 값을 가져와 googleMapApiKey 변수에 저장한다.

-  getLatLngByAddress 메서드에서 API 키가 담긴 GeoApiContext와 전체 주소로 GeocodingApi에 주소에 대한 지오코딩을 요청한다. 위도와 경도는 results 배열에 담긴다.

- 데이터가 잘 들어왔으면 위도 경도 변수에 각각 결괏값을 저장해주고 AddressResponse로 응답한다.

 

AddressResponse는 아래와 같이 구성했다.

@Getter
@AllArgsConstructor
public class AddressResponse {

  private double latitude;
  private double longitude;
}

 

주소의 정확성을 위해 5자리 우편번호를 받을 것이기 때문에 CreateRequest에는 아래와 같은 Valid 제한을 걸어줬다.

@NotEmpty
@Pattern(regexp = "\\d{5}", message = "주소는 5자리 숫자 우편번호 형식이어야 합니다.")
private String address;

 

4) 결과

허브를 생성할 때 우편번호를 입력하면 위도와 경도를 구해오는 로직을 개발한 것이기 때문에,

허브 Service에 아래와 같은 로직을 추가해 지오코딩을 사용했다.

AddressResponse latLngByAddress = geocodingService.getLatLngByAddress(
        hubCreateRequest.getAddress());

 

그 결과 우편번호가 위도와 경도로 잘 들어간 것을 볼 수 있다.

직접 위도와 경도로 주소값과 일치하는 지 찾아본 결과 일치했다.