1. 출발지, 목적지 등 필요한 정보 입력하지 않았을 때
redius.js, waypoints.js의 마지막 부분에 다음과 같은 코드를 추가했다.
try {
if (originAddress === "" || redius === "" || waypointNum === "" || secondType === "")
throw new Error("값이 입력 되지 않았습니다.");
}catch (e)
{
alert(e.message);
return;
}
위 코드의 결과는 아래와 같다.
또한 RealRandomRouteSearchService에도 해당 예외처리를 넣어줬다.
코드가 변경되며 프론트에서 전달한 값은 제대로 못받을 수도 있기 때문이다.
추가한 예외처리 방식은 다음과 같다.
if (ObjectUtils.isEmpty(originAddress) || ObjectUtils.isEmpty(distance)) {
throw new IllegalArgumentException("출발지 또는 목적지 주소 또는 경유지 수 또는 거리가 비어있습니다.");
}
2. 경유지 or 목적지까지 경로를 안내할 수 없어 data를 받아올 수 없을 때
navi.js에서 검사하는 방식이 가장 빠르고 쉬운 방법이라고 생각해서 navi.js에 다음 코드를 추가했다.
function isDataExist(data) {
try {
if (data === null)
throw new Error("data가 생성되지 않았습니다.");
}catch (e)
{
alert(e.message);
return;
}
}
하지만 데이터를 다시 가져오는것에 대해서는 생각해볼 필요가 있을 것 같다.
경유지나 목적지가 갈 수 없는 위치일 때와, 경유지와 목적지 자체를 찾지 못할 때가 따로 존재하기 때문이다.
또한 확인해보니 이미 data에 따라 예외처리 해주는 부분이 존재해서 이 부분은 추가하지 않기로 했다.
아래는 채택된 예외처리 방식이다.
fetch('/api/route?originAddress=' + currectAddress + '&destinationAddress=' + destinationAddress)
.then(response => response.json())
.then(data => {
responseData = data;
adapt_KakaoResponseToRouteData(data);
makeLiveMap(data)
clearNavi();
})
.catch(error => {
alert("경로를 생성할 수 없습니다. 다시 시도해 주세요");
console.log(error);
window.location.href = '/view/home';
});
맨 마지막의 catch 부분을 보면 안내알람, 에러로그, 홈페이지로 이동을 수행한다.
3. 특정 좌표 주변의 목적지, 경유지를 찾을 수 없을 때
각각의 경로 탐색 옵션에서 경유지를 찾는 방식이 다르기 때문에 각각의 경우를 나눠서 예외처리를 시도했다.
아래의 모든 과정은 RealRandomRouteSearchService에서 이뤄진다.
다음 링크를 참고하면 상세 내용을 알 수 있다. https://hwk99.tistory.com/121
- 출발지, 목적지 주소를 좌표로 변환하지 못함
출발지, 목적지를 기입하는 requestRandomWay에 추가한 코드는 아래와 같다.
각각 이미 채택된 예외처리 방식을 이용했다.// 출발지 주소를 좌표로 변환 List<DocumentDto> originList = kakaoAddressSearchService.requestAddressSearch(originAddress).getDocumentDtoList(); if (originList.isEmpty()) { throw new IllegalArgumentException("출발지 주소를 찾을 수 없습니다."); } DocumentDto origin = originList.get(0); //목적지 주소를 좌표로 전환 List<DocumentDto> destinationList = kakaoAddressSearchService.requestAddressSearch(destinationAddress).getDocumentDtoList(); if (destinationList.isEmpty()) { throw new IllegalArgumentException("도착지 주소를 찾을 수 없습니다."); } DocumentDto destination = destinationList.get(0);
출발지만 입력하는 requestAllRandomWay에는 다음과 같이 코드를 추가해 목적지를 가져올 수 있는 확률을 높혔다.
시도횟수가 3번이나 늘어났으니 대부분 상황에서 목적지를 특정할 수 있다.
// 목적지를 가져오지 못하면 3번 더 반복 for (int i = 0; i < 3; i++) { if (destination == null) destination = getDestination(originY, originX, convertedDistance); else break; } if (destination == null) { throw new NullPointerException("목적지를 찾을 수 없습니다. 범위를 수정해보거나 다시 시도해주세요."); }
- 목적지
getDestination메서드에 다음과 같은 기능을 추가한다. 목적지를 못찾았다는 뜻이다.
목적지를 가져오지 못하는 상황에 대비해 다음과 같이 코드를 추가한다.if (randomLength == 0) { return null; }
만일 3번의 추가적인 시도 끝에도 목적지를 찾지 못하면 위와같은 안내문구를 띄워준다.// 목적지를 거리 기반으로 무작위적으로 가져오는 메소드 DocumentDto destination = getDestination(originY, originX, convertedDistance); // 목적지를 가져오지 못하면 3번 더 반복 for (int i = 0; i < 3; i++) { if (destination == null) destination = getDestination(originY, originX, convertedDistance); else break; } if (destination == null) { throw new NullPointerException("목적지를 찾을 수 없습니다. 범위를 수정해보거나 다시 시도해주세요."); }
- 직선경로
경유지를 탐색하는 범위가 좁은 직선 경로의 경우, 만일 특정 지점 주변에 경유지 후보군이 없을 때, waypoints에 null 값을 넣어주지 않는 방법 말고는 생각이 나지 않았다. 범위를 넓혀서 다시 찾는다면 이는 직선경로가 아닌 지그재그 경로가 되어버린다. 고로 직선 경로에는 아래와 같이 짧은 코드만 추가했다.
wayPoints에 null 값을 넣지 않는 것이 목적인 코드이다.if (wayPoint != null) wayPoints.add(wayPoint);
- 지그재그 경로
참.. 문제가 많은 코드이다. 실행속도가 심각하게 느려 개선이 필요하다.
직선경로처럼 단순하게 해결하는 방법도 있었지만, 이왕 칸으로 나눠놓은거 나눠놓은 칸 중 하나라도 wayPoint가 존재한다면, wayPoints에 더해주는 방식을 접근시켰다.
추가한 코드의 예시는 아래와 같다.
for (int j = 0; j < count; j++) { // 경유지 찾을 때까지 해당 범위의 모든 구역 탐색 double randomX = middleX - sideLength / 2 + sideLength / count * ((randomNum+j)%count); double redius = Math.min(sideLength/count * 100, 20); RandomDocumentDto wayPoint = getRandomWayPoint(randomY, randomX, redius); if (wayPoint != null) { wayPoints.add(wayPoint); break; } }
- 순환형 경로
순환형 경로는 정해진 범위 안에서 다시 랜덤을 이용하기보다는, 목적지 탐색 위치를 중점의 위치에 점점 가깝게 하는 방식으로 찾아보았다. 확실히 지그재그보다 속도가 높다. 하지만 여전히 속도가 너무나 느리다..
적용시킨 코드는 아래와 같다.
for (double temp = redius; temp > 0.02; temp -= 0.02) { // 경유지 찾을 때까지 반지름 내부 모든 구역 탐색 double wayPointY = rediusY + redius * Math.sin(wayPointRadian); double wayPointX = rediusX + redius * Math.cos(wayPointRadian); System.out.println("정점" + (i+1) + " : " + wayPointY + ", " + wayPointX); RandomDocumentDto wayPoint = getRandomWayPoint(wayPointY, wayPointX, 2); if (wayPoint != null) { wayPoints.add(wayPoint); break; } }
4. History 관련 예외처리
아주 빡빡하게 하나하나 예외처리를 하기보다는 큰 데이터에 대한 예외처리만 해주었다.
이유는 for문 내부에 if문이 하나씩 들어가게 되면, 처리 시간에 큰 영향을 주기 때문이다.
또한 큰 데이터를 저장하다보니, 의도하지 않은 데이터가 한두개 들어갈 수 있는데, 이는 카카오 API의 문제이기 때문이다.
- saveHistory
다음과 같은 두번의 예외처리를 해주었다
아래 코드는 맨 처음 들어오는 정보들에 값이 들어있는지 검사해준다.
다음 코드는 랜덤 경로 생성중 목적지까지 제대로 생성이 되었는지 검사해준다.if (ObjectUtils.isEmpty(originAddress) || ObjectUtils.isEmpty(requestDto) || ObjectUtils.isEmpty(destinationAddress) || ObjectUtils.isEmpty(mapType)) { throw new IllegalArgumentException("출발지 또는 목적지 주소 또는 도로 정보가 전달되지 않았습니다."); }
if (mapType.equals("live-all-random")) { RandomDestination olderRandomDestination = randomDestinationRepository.findByUserId(user.getId()); if (olderRandomDestination == null) { throw new EntityNotFoundException("경로를 저장할 수 없습니다."); } destinationAddress = olderRandomDestination.getDestinationAddress(); }
- getHistory
이미 예외처리를 해뒀던 코드이다. 그래도 소개를 하자면, 아래같이 경로 상세 정보를 가져올 수 없을때 발생한다.
Route route = routeRepository.findById(routeId).orElse(null); if (route == null) { // 해당 routeId에 대한 정보가 없을 경우 예외 처리 또는 적절한 응답을 반환 throw new IllegalArgumentException("해당 경로를 가져올 수 없습니다."); }
'프로젝트 > RanDrive' 카테고리의 다른 글
성능개선(DB 호출 수 줄이기, DB 처리 속도 향상시키기) (1) | 2023.11.04 |
---|---|
기능 개선(새로운 랜덤 길찾기 알고리즘 프론트 코드 작성) (1) | 2023.11.01 |
기능 개선(경유지를 가진 경로 이탈 시 처리) (0) | 2023.11.01 |
기능 개선(JMeter) (0) | 2023.10.30 |
기능 개선(랜덤 길찾기 알고리즘) (0) | 2023.10.28 |