diff --git a/src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java b/src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java index d0ba3c76..09413004 100644 --- a/src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java +++ b/src/main/java/com/wayble/server/direction/exception/WalkingErrorCase.java @@ -12,6 +12,7 @@ public enum WalkingErrorCase implements ErrorCase { GRAPH_FILE_NOT_FOUND(500, 8002, "그래프 파일을 찾을 수 없습니다."), GRAPH_INIT_FAILED(500, 8003, "그래프 초기화에 실패했습니다."), NODE_NOT_FOUND(400, 8004, "해당 위도, 경도 근처의 노드가 존재하지 않습니다."), + DISTANCE_LIMIT_EXCEEDED(400, 8005, "경로가 허용 최대 거리(30km)를 초과하였습니다."), ; private final Integer httpStatusCode; diff --git a/src/main/java/com/wayble/server/direction/service/WalkingService.java b/src/main/java/com/wayble/server/direction/service/WalkingService.java index 460c714b..f384e347 100644 --- a/src/main/java/com/wayble/server/direction/service/WalkingService.java +++ b/src/main/java/com/wayble/server/direction/service/WalkingService.java @@ -27,6 +27,8 @@ public class WalkingService { private final GraphInit graphInit; private final WaybleDijkstraService waybleDijkstraService; + private static final double NODE_SEARCH_RADIUS = 1000; + public TMapParsingResponse callTMapApi(TMapRequest request) { try { TMapResponse response = tMapClient.response(request); @@ -52,6 +54,7 @@ public WayblePathResponse findWayblePath( private long findNearestNode(double lat, double lon) { return graphInit.getNodeMap().values().stream() + .filter(node -> HaversineUtil.haversine(lat, lon, node.lat(), node.lon()) <= NODE_SEARCH_RADIUS) .min(Comparator.comparingDouble( node -> HaversineUtil.haversine(lat, lon, node.lat(), node.lon()) )) diff --git a/src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java b/src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java index 8c847154..3a5b837c 100644 --- a/src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java +++ b/src/main/java/com/wayble/server/direction/service/WaybleDijkstraService.java @@ -1,10 +1,13 @@ package com.wayble.server.direction.service; +import com.wayble.server.common.exception.ApplicationException; import com.wayble.server.direction.dto.response.WayblePathResponse; import com.wayble.server.direction.entity.Edge; import com.wayble.server.direction.entity.Node; import com.wayble.server.direction.entity.type.Type; +import com.wayble.server.direction.exception.WalkingErrorCase; import com.wayble.server.direction.init.GraphInit; +import com.wayble.server.direction.service.util.HaversineUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,12 +21,20 @@ public class WaybleDijkstraService { // 11cm의 오차 허용 private static final double TOLERANCE = 0.000001; + private static final double MAX_DISTANCE = 30000.0; public WayblePathResponse createWayblePath(long start, long end) { List path = dijkstra(start, end); Map markerMap = graphInit.getMarkerMap(); - int totalDistance = (int) Math.round(calculateDistance(path)); + List polyline = createPolyLine(path); + double totalDistanceMeters = calculateDistance(polyline); + + if (totalDistanceMeters >= MAX_DISTANCE) { + throw new ApplicationException(WalkingErrorCase.DISTANCE_LIMIT_EXCEEDED); + } + int totalDistance = (int) Math.round(totalDistanceMeters); + // 노드 간 5초 대기 시간 추가 (횡단 보도, 보행자 상황 등 반영) int totalTime = (int) Math.round(calculateTime(path)) + path.size() * 5; @@ -34,8 +45,6 @@ public WayblePathResponse createWayblePath(long start, long end) { return new WayblePathResponse.WayblePoint(node.lat(), node.lon(), type); }).toList(); - List polyline = createPolyLine(path); - return WayblePathResponse.of(totalDistance, totalTime, wayblePoints, polyline); } @@ -109,17 +118,14 @@ private double calculateTime(List path) { return totalTime; } - private double calculateDistance(List path) { + private double calculateDistance(List polyline) { double totalDistance = 0.0; - for (int i = 0; i < path.size() - 1; i++) { - long from = path.get(i); - long to = path.get(i + 1); - totalDistance += graphInit.getGraph().getOrDefault(from, List.of()).stream() - .filter(edge -> edge.to() == to) - .findFirst() - .map(Edge::length) - .orElse(0.0); + for (int i = 1; i < polyline.size(); i++) { + totalDistance += HaversineUtil.haversine( + polyline.get(i - 1)[1], polyline.get(i - 1)[0], + polyline.get(i)[1], polyline.get(i)[0] + ); } return totalDistance; }