<template>
<div>
<input v-model="departure" placeholder="출발지 입력" />
<input v-model="destination" placeholder="도착지 입력" />
<button @click="searchRoute">경로 검색</button>
<div id="map" ref="mapRef" style="width:100%;height:500px;"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';
const mapRef = ref(null);
const departure = ref('');
const destination = ref('');
let map = null;
onMounted(() => {
if (window.naver && window.naver.maps) {
initMap();
} else {
const script = document.createElement('script');
script.src = `https://oapi.map.naver.com/openapi/v3/maps.js?ncpClientId=CLIENT_ID&submodules=geocoder`;
script.onload = initMap;
document.head.appendChild(script);
}
});
function initMap() {
const mapOptions = {
center: new window.naver.maps.LatLng(37.519259, 127.034426),
zoom: 17
};
map = new window.naver.maps.Map(mapRef.value, mapOptions);
}
async function searchRoute() {
if (!departure.value || !destination.value) {
alert('출발지와 도착지를 모두 입력해주세요.');
return;
}
await searchAddress(departure.value, 'departure');
await searchAddress(destination.value, 'destination');
}
async function searchAddress(query, type) {
try {
const response = await axios.get('/api/map-geocode/v2/geocode', { //https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode
params: {
query: query,
},
headers: {
'X-NCP-APIGW-API-KEY-ID': CLIENT_ID,
'X-NCP-APIGW-API-KEY': CLIENT_SECRET,
}
});
if (response.data.status === 'OK' && response.data.addresses.length > 0) {
const result = response.data.addresses[0];
const latLng = new window.naver.maps.LatLng(result.y, result.x);
if (type === 'departure') {
console.log('출발지:', result.roadAddress);
new window.naver.maps.Marker({
position: latLng,
map: map,
icon: {
content: '<div style="background-color:blue;color:white;padding:3px;">출발</div>',
anchor: new window.naver.maps.Point(20, 20)
}
});
} else {
console.log('도착지:', result.roadAddress);
new window.naver.maps.Marker({
position: latLng,
map: map,
icon: {
content: '<div style="background-color:red;color:white;padding:3px;">도착</div>',
anchor: new window.naver.maps.Point(20, 20)
}
});
}
map.setCenter(latLng);
} else {
alert('검색 결과가 없습니다!');
}
} catch (error) {
console.error('Error:', error);
alert('검색 중 오류가 발생했습니다.');
}
}
</script>
이렇게 코드 작성해서
gecoding으로 naver maps 에 요청을 통해서 값을 받으려고 하였으나,
네이버 정책이 그렇다고 합니다.
이를 해결하기 위해서는 백엔드 서버를 통해서 요청을 하든가, 프록시 서버를 통해서 요청을 해야하는데
어차피 백엔드 서버를 구현할 예정이기 때문에 백엔드 코드를 하드 코딩하여 요청을 해보았습니다.
@RestController
public class HomeController {
String clientId;
String clientSecret;
String query = "불정로 6";
@RequestMapping("/")
public String home() {
return "Hello, World";
}
@RequestMapping("/api/geocode")
public String getGeocode() {
try {
RestTemplate restTemplate = new RestTemplate();
// String encodedQuery = URLEncoder.encode(query, "UTF-8");
URI uri = new URI("https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=불정로%206");
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
headers.set("X-NCP-APIGW-API-KEY-ID", clientId);
headers.set("X-NCP-APIGW-API-KEY", clientSecret);
headers.set("Content-Type", "application/json");
org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<>("parameters", headers);
org.springframework.http.ResponseEntity<String> response = restTemplate.exchange(uri, org.springframework.http.HttpMethod.GET, entity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
String responseBody = response.getBody();
// if (responseBody.contains("\"totalCount\":0")) {
// System.out.println("검색 결과 없음");
// return "검색된 결과가 없습니다.";
// }
return responseBody;
} else {
System.out.println("Error: " + response.getStatusCode() + " - " + response.getBody());
return "Error occurred";
}
} catch (URISyntaxException e) {
e.printStackTrace();
return "Error: Invalid URI or Encoding issue.";
} catch (Exception e) {
e.printStackTrace();
return "Error occurred while processing the request.";
}
}
}
원하는 주소의 경우 원래는 프론트에서 값을 전달 받아 넣어줘야 하지만 간단하게 테스트 하기 위해서 여기서는
clietId와 clientSecret, query(원하는 주소)를 하드 코딩하여 넣어줘서 테스트를 진행하였습니다.
엥 근데 결과가 200이 떨어지고 성공했다고 하는데 나오는 값이 하나도 없습니다.
열심히 찾아본 결과
clietId와 clientSecret의 값을 확인하고, url 주소를 확인하라고 하여 확인해 봤으니 여전히 같은 결과가 나오고 있다.
이걸로 4시간은 날린거 같습니다....
그러나 한가지 이유가 남았었는데 '불정로 6'으로 넣은 값이 encoding이 안되어서 라는 단서를 찾아서 변경해주고 해결했습니다.
변경된 코드는
@RestController
public class HomeController {
String clientId;
String clientSecret;
String query = "불정로 6";
@RequestMapping("/")
public String home() {
return "Hello, World";
}
@RequestMapping("/api/geocode")
public String getGeocode() {
try {
RestTemplate restTemplate = new RestTemplate();
String encodedQuery = URLEncoder.encode(query, "UTF-8");
URI uri = new URI("https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=" + encodedQuery);
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
headers.set("X-NCP-APIGW-API-KEY-ID", clientId);
headers.set("X-NCP-APIGW-API-KEY", clientSecret);
headers.set("Content-Type", "application/json");
org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<>("parameters", headers);
org.springframework.http.ResponseEntity<String> response = restTemplate.exchange(uri, org.springframework.http.HttpMethod.GET, entity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
String responseBody = response.getBody();
if (responseBody.contains("\"totalCount\":0")) {
System.out.println("검색 결과 없음");
return "검색된 결과가 없습니다.";
}
return responseBody;
} else {
System.out.println("Error: " + response.getStatusCode() + " - " + response.getBody());
return "Error occurred";
}
} catch (URISyntaxException | UnsupportedEncodingException e) {
e.printStackTrace();
return "Error: Invalid URI or Encoding issue.";
} catch (Exception e) {
e.printStackTrace();
return "Error occurred while processing the request.";
}
}
}
근데 보다 보니 또 문제가 생겼습니다.
검색의 문제는 아니고 보통은 주소를 검색할 때
서울시청, 서울역 이런식으로 랜드마크의 이름으로 검색을 하는데 naver maps에서 제공하는 geocoding으로는 불정로 6 같은 주소로만 검색이 가능하다는 거...
아마 네이버 개발자 센터에 있는 검색 API를 다시 사용해서 가공해서 가져와야 할거 같습니다.
일단은 이 문제는 나중으로 미루고 출발지와 도착지의 거리를 정보를 받는 코드를 구현 후에 다시 달아야 할 거 같습니다.
'네이버 맵스(Naver Maps) API' 카테고리의 다른 글
Vue.js + Spring 네이버 맵스 사용하기 4 (Direction 5 API) (0) | 2025.01.13 |
---|---|
Vue.js + Spring 네이버 맵스 사용하기 3 (프론트와 백엔드 연결) (0) | 2025.01.10 |
Vue.js + Spring 네이버 맵스 사용하기 1 (기본 네이버 맵스 실행시키기) (0) | 2025.01.09 |