스터디일지/PROJECT

Final Project - Random Navi - 기본 길 찾기 경로 이탈 처리하기

똥쟁이핑크 2023. 10. 30. 21:42

내비게이션 안내에 따라 이동하다가 길을 잘 못 들었을 때를 경로 이탈로 간주하고 
현재 있는 위치 정보를 받아서 (api로 요청 받기) 현재 위치로부터 경로를 재 생성 해주는 알고리즘을 구현하고자 한다.

정보를 입력 받고 


 

경로를 안내 받고 안내 시작을 누르면 

경로 안내가 시작이 된다..
그런데 운전을 하다 보면 경로를 이탈하는 경우가 아주 가끔 생긴다.
1) 옆 사람과 이야기하다가 경로를 이탈한 경우
2) 안내받은 경로가 갑자기 막히는 경우 →  도로에서 사고가 나는 경우 혹은 공사를 하는 경우
이것 말고도 더 있겠지만 결과적으로 경로를 이탈했을 때 이탈 한 곳으로부터 경로를 다시 안내해 줘야 하는데 
그 부분에 대한 구현이 안되어 있어서 구현 하고자 한다.

내가 생각한 재 생성 방법으로는

출발지 → 목적지로 설정된 경로에서

이탈한 나의 위치 → 기존에 설정된 목적지로 경로를 새로 만들어 주는 것이다.

 

첫 번째로 조원들이 만들어둔 길찾기 코드를 활용하기로 했다.
1) calculation.js → update

2) navi.js → makeLiveMap
위의 두개의 파일에 있는 함수를 활용하기로 했다.

 

이탈하는 상황은 마우스로 안내받은 경로 말고 다른 지점을 클릭하는 것으로 이탈하는 상황을 만들었고 
생각한 대로라면 calculation.js에서 이탈한 지점의 위도와 경도의 값을 가져오는 함수인 updateMap을 이용해서

 makeLiveMap 에 활용하려 했는데 결과적으로는 반복된 코드가 많아져서 가독성도 떨어지고 충돌이 발생했다.

 

 그래서 Controller 부터 차근차근 다시 만들어 봤다.
RouteController는 경로 생성을 컨트롤한다. 그래서  reroute라고 GetMapping을 새로 만들어 주고 RequestBody로 위도 경도를 받아 줬는데 이 부분은 RequestParam으로 바꿔 주었다.

 @GetMapping("/reroute")
    public ResponseEntity<KakaoRouteAllResponseDto> getReRoute(@RequestParam double lat, double lng) {
		//코드 일부분 첨부
        return new ResponseEntity<>(response, HttpStatus.OK);
}


Service는 KakaoRouteSearchService에서 Controller에서 넘어온 위도와 경도를 parameter로 받아서 startCoord(새로운 경로 출발) 변수에 넣어줬다.

public KakaoRouteAllResponseDto requestRouteReSearch(double lat, double lng) {
	 double startCoord = Double.parseDouble(lat + "," + lng);
	//코드 일부분 첨부
     return restTemplate.exchange(uri, HttpMethod.GET, httpEntity, KakaoRouteAllResponseDto.class).getBody();
}

 

startCoord는 KakaoUriBuilderService에서 카카오에 요청할 uri로 만들어 준다.

public URI buildUriByReRouteSearch(double startCoord) {
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(KAKAO_ROUTE_SEARCH_URL);
		// 코드 일부분 첨부
		return routeUri;
}

 

navi.js에서는 길찾기 함수를 이용해서 새로운 함수를 만들었다.

function remakeNavi(lat, lng) { 
	....
    fetch( 코드 작성 하기)
        
        ......
        makeLiveMap(data)
        ......

}

remakeNavi에 있는 lat, lng는 경로 이탈한 위도와 경도 좌표다

fetch는 아래 코드 처럼 변형을 줬다.

// 1번 코드
fetch('/api/reroutestartAddress=' + lat  + 'lng=' + lng)

// 2번 코드
fetch('/api/reroutestartAddress='lat + lng)

// 3번 코드
fetch('/api/reroutestartAddress=${lat}+${lng}')

// 4번 코드
fetch('/api/reroutestartAddress=${lat}${lng}')

 

변형을 준 이유는 

 

위와 같은 에러가 계속 떴고 경로 주소가 %E%S%ER 이런 식으로도 작성이 되었다.

이것 말고도 다른 에러 메시지도 있었는데 에러 메시지는 다음과 같았다.

1) 유효하지 않은 출발지 입니다. 

2) Required request parameter 'lat' for method parameter type double is not present]


카카오 api문서는

이렇게 나와있었기 때문에 계속 수정을 했는데도 같은 결과가 계속 됐다.

 

주소가 %E%S%ER 이렇게 나오는 부분은 잘못된 문자로 인식하고 있어서 디코딩을 해주었다.

 

또한 새로운 경로를 생성하려면 이탈한 곳으로의 좌표 정보 즉 주소 정보가 필요했다.

그래서 아래 코드처럼 좌표정보를 지도에 넘겨주고 주소 정보를 가져왔다.

 

주소 정보를 가져왔기 때문에 그 주소를 이용해서 길 찾기 api 요청을 한번 더 했고 data 정보를 받아서 makeLiveMap에 넣어 주었다.

 

const segments = decodeURIComponent(url).split("/"); // 주소 디코딩



function remakeNavi(lat, lng) { 
	....
    // 최종
     fetch(
        'https://dapi.kakao.com/v2/local/geo/coord2address?x=' + lng + '&y=' + lat,
        {
            headers: { Authorization: 'KakaoAK rest api키 넣기' }, 
        }
        
        	
            
            currectAddress = data.documents[0].address.address_name; // 이탈한 곳의 주소 정보
            
            fetch('/api/route?currectAddress=' + currectAddress  + '&destinationAddress=' + destinationAddress)
        
                ......
                makeLiveMap(data)
                ......

}

 

makeLiveMap 함수에서는 위의 정보를 받아서 경로를 재 생성 한다.

navi.js 에서 지금은 update-refact라는 함수로 이름이 바뀌었지만 바꾸기 전인 updateMap 함수에서 

CurrectToPos , PastToPos의 값이 null값이 들어갔고 그로 인해 js에서 값이 NaN이 되었을 때 NaN 오류 메시지가 그대로 변수의 값으로 들어가는 상황이었다.

이유는 js에서는 자동으로 변수의 타입을 정해버리기 때문이라고 한다. 그래서 변수를 먼저 선언했고 그다음에 변수명 = 계산식 이렇게 바꿔서 해결했다.

function update_refact(lat, lng){
	........
    // 코드 일부분 첨부 
// 고치기 전 
        let roadPartLength = calculateDistance(vex[lastRoadIndex + 3], vex[lastRoadIndex + 2],vex[lastRoadIndex + 1], vex[lastRoadIndex]);
        let PastToPos = calculateDistance(vex[lastRoadIndex + 1], vex[lastRoadIndex], lat, lng);
        let CurrectToPos = CurrectToPos = calculateDistance(vex[lastRoadIndex + 3], vex[lastRoadIndex + 2], lat, lng);

        // 고친 후 
        let roadPartLength = calculateDistance(vex[lastRoadIndex + 3], vex[lastRoadIndex + 2],vex[lastRoadIndex + 1], vex[lastRoadIndex]);
        let PastToPos = calculateDistance(vex[lastRoadIndex + 1], vex[lastRoadIndex], lat, lng);
        let CurrectToPos = 0;
        CurrectToPos = calculateDistance(vex[lastRoadIndex + 3], vex[lastRoadIndex + 2], lat, lng);

	..............
}

 

 

경로 이탈 시 재생성하는 결과는 다음과 같다.

 

1. 가고자 하는 경로를 안내받고 

 

 

2. 출발지 위치를 확인했다. 그리고 마우스로 다른 좌표를 찍어서 경로 이탈 상황을 만들었다

 

 

3. 일부러 먼 곳을 클릭했고 경로가 재 생성되었다.

출발지 위치나 중간에 경로를 이동하다가 이탈하더라도 
경로 생성이 잘되는 것을 확인했다.