- 기본, 랜덤 길찾기 네비게이션 기능 구현 완료
- 출발지, 목적지 입력 후 길찾기 경로를 미리 보여줄 때, 전체 경로가 보여야 되는데, 일부 경로의 길이만 바운딩 박스로 가져오고 있다. 전체 경로가 보여지게 수정하기.
일부 경로만 보임
전체 경로가 보여야함
public void saveHistory(KakaoRouteAllResponseDto requestDto, String originAddress, String destinationAddress, String mapType, User user) {
for (KakaoRouteAllResponseDto.RouteInfo routeInfo : requestDto.getRoutes()) {
KakaoRouteAllResponseDto.Summary summary = routeInfo.getSummary();
KakaoRouteAllResponseDto.Section section = routeInfo.getSections()[0]; // 첫 번째 Section을 사용하겠습니다.
if (mapType.equals("live-all-random")) {
RandomDestination olderRandomDestination = randomDestinationRepository.findByUsername(user.getUsername());
destinationAddress = olderRandomDestination.getDestinationAddress();
}
// Route 객체 생성
Route route = new Route(originAddress, destinationAddress, mapType, summary.getDuration(), summary.getDistance(), user);
// Bound 객체 생성 및 설정
KakaoRouteAllResponseDto.BoundingBox bound = section.getBound();
double min_x = bound.getMinX();
double min_y = bound.getMinY();
double max_x = bound.getMaxX();
double max_y = bound.getMaxY();
double ori_x = summary.getOrigin().getX();
double ori_y = summary.getOrigin().getY();
double des_x = summary.getDestination().getX();
double des_y = summary.getDestination().getY();
min_x = Math.min(min_x, Math.min(ori_x, des_x));
min_y = Math.min(min_y, Math.min(ori_y, des_y));
max_x = Math.max(max_x, Math.max(ori_x, des_x));
max_y = Math.max(max_y, Math.max(ori_y, des_y));
for (int i = 0; i < summary.getWaypoints().length; i++) {
double waypoint_x = summary.getWaypoints()[i].getX();
double waypoint_y = summary.getWaypoints()[i].getY();
min_x = Math.min(min_x, waypoint_x);
min_y = Math.min(min_y, waypoint_y);
max_x = Math.max(max_x, waypoint_x);
max_y = Math.max(max_y, waypoint_y);
}
Bound boundEntity = new Bound(min_x, min_y, max_x, max_y,route);
// RouteRepository를 사용하여 Route 저장
routeRepository.save(route);
boundRepository.save(boundEntity);
// Road 객체 생성 및 설정
KakaoRouteAllResponseDto.Section[] sections = routeInfo.getSections();
// for문 돌면서 모든 Road의 vertexes를 vertexString에 띄어쓰기로 구분해서 넣어라
for (KakaoRouteAllResponseDto.Section allSection : sections) {
KakaoRouteAllResponseDto.Road[] roads = allSection.getRoads();
for (KakaoRouteAllResponseDto.Road roadDto : roads) {
String vertexesString = "";
vertexesString += Arrays.stream(roadDto.getVertexes()).mapToObj(String::valueOf).collect(Collectors.joining(" "));
Road roadEntity = new Road(vertexesString, route);
roadRepository.save(roadEntity);
}
}
}
}
- 모든 경로에 대한 좌표를 bound 객체로 생성해서 그 화면을 보여주는 형식
function makeLiveMap(data) {
clearPolylines(); // 기존의 선들을 모두 제거
if (!map) {
map = new kakao.maps.Map(document.getElementById('map'), {
level: 3
});
}
// 경로 정보(routes)의 각 섹션(section)별로 반복하여 처리합니다.
for (let route of data.routes) {
let distance = route.summary.distance;
let duration = route.summary.duration;
// distance와 duration을 표시할 요소를 선택
let distanceElement = document.querySelector('.distance');
let durationElement = document.querySelector('.duration');
let hour = Math.floor(duration / 3600);
let minute = Math.floor((duration % 3600) / 60);
let km= (distance / 1000).toFixed(1);
// 요소에 데이터를 추가
distanceElement.textContent = '소요 시간: ' + hour + '시간 ' + minute + '분';
durationElement.textContent = '총 거리: ' + km + ' km';
for (let section of route.sections) {
// 각 섹션의 경계 상자(bound) 정보를 가져옵니다.
let bound = section.bound;
// 카카오 지도에 섹션을 표시합니다.
var bounds = new kakao.maps.LatLngBounds(
new kakao.maps.LatLng(bound.min_y, bound.min_x),
new kakao.maps.LatLng(bound.max_y, bound.max_x)
);
map.setBounds(bounds);
// polyline 생성
for(let road of section.roads){
let path = [];
for(let i=0; i<road.vertexes.length; i+=2){
console.log("vertexes: ", road.vertexes[i], road.vertexes[i+1]);
path.push(new kakao.maps.LatLng(road.vertexes[i+1], road.vertexes[i]));
}
let polyline = new kakao.maps.Polyline({
path: path,
strokeWeight: 5,
strokeColor: '#007bff',
strokeOpacity: 0.7,
strokeStyle: 'solid'
});
polyline.setMap(map);
polylines.push(polyline); // 선을 배열에 추가
}
}
}
}
function makeLiveMap(data) {
clearPolylines(); // 기존의 선들을 모두 제거
if (!map) {
map = new kakao.maps.Map(document.getElementById('map'), {
level: 3
});
}
var bounds = new kakao.maps.LatLngBounds(); // 모든 경로의 좌표를 포함할 수 있는 경계 객체를 만듭니다.
// 경로 정보(routes)의 각 섹션(section)별로 반복하여 처리합니다.
for (let route of data.routes) {
let distance = route.summary.distance;
let duration = route.summary.duration;
// distance와 duration을 표시할 요소를 선택
let distanceElement = document.querySelector('.distance');
let durationElement = document.querySelector('.duration');
let hour = Math.floor(duration / 3600);
let minute = Math.floor((duration % 3600) / 60);
let km = (distance / 1000).toFixed(1);
// 요소에 데이터를 추가
distanceElement.textContent = '소요 시간: ' + hour + '시간 ' + minute + '분';
durationElement.textContent = '총 거리: ' + km + ' km';
for (let section of route.sections) {
// 각 섹션의 경로를 순회하면서 모든 좌표를 경계 객체에 추가합니다.
for (let road of section.roads) {
let path = [];
for (let i = 0; i < road.vertexes.length; i += 2) {
let latLng = new kakao.maps.LatLng(road.vertexes[i + 1], road.vertexes[i]);
bounds.extend(latLng); // 경계를 확장하여 이 좌표를 포함하도록 합니다.
path.push(latLng);
}
let polyline = new kakao.maps.Polyline({
path: path,
strokeWeight: 5,
strokeColor: '#007bff',
strokeOpacity: 0.7,
strokeStyle: 'solid'
});
polyline.setMap(map);
polylines.push(polyline); // 선을 배열에 추가
}
}
}
map.setBounds(bounds); // 새로 계산된 경계를 지도에 적용합니다.
}
- 첫 번째 코드에서는 각 섹션의 모든 좌표를 지도 경계 객체(bounds object)에 추가하여 지도의 경계를 확장 = 이 방법은 모든 좌표를 포함하도록 지도 경계를 동적으로 조정하기 때문에 지도에 모든 섹션의 경로가 정확하게 표시된다.
- 반면에 두 번째 코드에서는 각 섹션의 경계 상자(bound) 정보만을 사용하여 지도의 경계를 설정 = 이 방법의 문제점은, 만약 경계 상자가 경로의 실제 좌표를 정확하게 반영하지 않는다면, 일부 경로가 지도에서 잘리거나 제대로 표시되지 않을 수 있습니다. 이는 경계 상자의
min_x, min_y, max_x, max_y
값이 경로의 모든 좌표를 정확히 반영하지 않기 때문에 발생한다.
- 또한, 두 번째 코드에서 각 섹션마다 map.setBounds(bounds);를 호출하는데, 이는 지도의 경계를 섹션의 경계 상자로 여러 번 재설정하게 되므로, 마지막 섹션의 경계 상자만 지도에 반영되고 이전 섹션들은 무시될 수 있다. 이로 인해 마지막 섹션만 제대로 표시되고 나머지 섹션은 지도에 표시되지 않는 문제가 발생할 수 있다.