Backend DEv

[Spring] 네이버 지도 길찾기 URL 제공 API

  • -
728x90

유저가 지정한 장소에 대해 네이버 지도앱의 길찾기 redirect URL을 구현하였다.

 

먼저 네이버 지도앱의 길찾기 URL을 확인하였다.

nmap://route/public?dlat={도착지 위도}&dlng={도착지 경도}dname={도착지 이름}

 

위 URL을 만들기 위해 위/경도를 가져와야 했는데, 이 부분은 네이버 지도 api 중 geocoding을 활용하였다. 자세한 설명은 아래 공식문서를 확인하자

https://api.ncloud-docs.com/docs/ai-naver-mapsgeocoding

 

Geocoding 개요

 

api.ncloud-docs.com

 

Geocoding 사용법

아래 내용은 위/경도 를 가져오기 위해 사용한 방법으로, URL을 만드는 것과는 연관성이 없다.

 

현재 네이버 지도 api는 naver cloud platform에 속해있다. 따라서 회원가입을 진행해야 한다. (23년 7월 기준으로 나중에 또 바뀔거 같다. 자주 바뀌는듯..)

https://www.ncloud.com/?language=ko-KR 

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

로그인 후 대시보드에서 AI·NAVER API 를 클릭한다.

그후 아래 화면에서 파란색 application 등록을 통해 새로 만들어준다. (staticMap도 사용할 줄 할고 해두었는데 사용하지 않았다.)

추가로, 네이버가 maps api를 모두 유료화하였기 때문에 무료이용량 횟수를 잘 보고 한도 횟수를 제한해두는 것이 좋을 것 같다.

 

현재 service는 아래와 같이 구현하였다. exception 일부는 또 수정해야 할 것 같다.

@Slf4j
@RequiredArgsConstructor
@Service
public class MapService {

    @Value("${api.naver-client-id}")
    String clientId;

    @Value("${api.naver-client-secret}")
    String clientSecret;

    public String getMapUrl(String reqLocation) throws BaseException {

        String resultUrl = null;
        try {
            String address = reqLocation;
            String addr = URLEncoder.encode(address, "UTF-8");

            log.debug("address = {}", address);

            String apiURL = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=" + addr;

            URL url = new URL(apiURL);
            log.debug("url = {}", url);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");

            con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
            con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);

            int responseCode = con.getResponseCode();

            BufferedReader br;

            if (responseCode == 200) {
                br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
            } else {
                br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
            }

            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }

            br.close();

            ObjectMapper objectMapper = new ObjectMapper();
            log.debug("response = {} response.string = {}", response, response.toString());

            JsonNode jsonNode = objectMapper.readTree(response.toString());
            log.debug("jsonNode = {}", jsonNode);
            JsonNode addressesNode = jsonNode.get("addresses");
            log.debug("addressesNode = {}", addressesNode);

            if (addressesNode != null && addressesNode.isArray()) {
                for (JsonNode addressNode : addressesNode) {
                    String roadAddress = getParsedUrl(addressNode.get("roadAddress").asText());
//                    String jibunAddress = addressNode.get("jibunAddress").asText();
                    String latitude = addressNode.get("y").asText();
                    String longitude = addressNode.get("x").asText();

                    log.debug("latitude = {} and longitude = {}", latitude, longitude);
                    resultUrl = "nmap://route/public?dlat=" + latitude + "&dlng=" + longitude + "&dname=" + roadAddress;
                }
            }
        } catch (UnsupportedEncodingException e) {
            log.debug("UnKnownAddrException 발생 ");
            throw new BaseException(ResponseStatus.UNKNOWN_ADDR);
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultUrl;
    }

    public String getParsedUrl(String roadAddress) throws UnsupportedEncodingException {
        String[] words = roadAddress.split(" ");
        String last_addr = words[words.length - 1];
        return URLEncoder.encode(last_addr, "UTF-8");
    }

}

일단은 쿼리스트링을 통해 정확한 주소를 입력받도록 하였는데, 완전 정확한 주소가 아니면 출력이 되지 않는 문제가 있어 이는 나중에 다시 해결해야 할 것 같다. 아마 카카오 api 로 변경해서 가져오도록 할 예정이다. 

 

현재 해당 코드는 카카오 api를 통해 유저가 지정한 location(ex. 아산병원)에 대해 그 장소에 대한 좌표를 확인하고, 그 값을 쿼리스트링으로 보내도록 하였다. 아래는 서비스단의 코드이다.

@Slf4j
@RequiredArgsConstructor
@Service
public class MapService {

    @Value("${api.kakao-rest-api-key}")
    String restApiKey;

    public String getMapUrl(String reqLocation) throws BaseException {

        String resultUrl = null;
        try {
            String address = reqLocation;
            String addr = URLEncoder.encode(address, "UTF-8");

            log.debug("address = {}", address);

            // Geocoding 개요에 나와있는 API URL 입력.
            String apiURL = "https://dapi.kakao.com/v2/local/search/keyword.json?page=1&size=1&sort=accuracy&query="+addr;

            URL url = new URL(apiURL);
            log.debug("url = {}", url);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");

            // 헤더
            con.setRequestProperty("Authorization", "KakaoAK " + restApiKey);

            // 요청 결과 확인. 정상 호출인 경우 200
            int responseCode = con.getResponseCode();

            BufferedReader br;

            if (responseCode == 200) {
                br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
            } else {
                br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
            }

            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }

            br.close();

            ObjectMapper objectMapper = new ObjectMapper();
            log.debug("response = {} response.string = {}", response, response.toString());

            JsonNode jsonNode = objectMapper.readTree(response.toString());
            log.debug("jsonNode = {}", jsonNode);
            JsonNode itemsNode = jsonNode.get("documents");
            log.debug("documents = {}", itemsNode);

            if (itemsNode != null && itemsNode.isArray() && itemsNode.size() > 0) {
                JsonNode firstItem = itemsNode.get(0);
                String mapx = firstItem.get("y").asText();
                String mapy = firstItem.get("x").asText();

                log.debug("mapx = {} and mapy = {}", mapx, mapy);
                resultUrl = "nmap://route/public?dlat=" + mapx + "&dlng=" + mapy + "&dname=" + addr;
            }
        } catch (UnsupportedEncodingException e) { // 에러가 발생했을 때 예외 status 명시
            log.debug("UnKnownAddrException 발생 ");
            throw new BaseException(ResponseStatus.UNKNOWN_ADDR);
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultUrl;
    }
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.