Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public enum ErrorCode {
FASTEST_ROUTE_NOT_FOUND(422, "경로가 없습니다."),
SAME_START_AND_END_POINT(400, "출발지와 도착지가 같습니다."),

// 루트
ROUTE_NOT_FOUND(404, "루트를 찾을 수 없습니다."),
CAUTION_DANGER_CANT_EXIST_SIMULTANEOUSLY(400, "위험요소와 주의요소는 동시에 존재할 수 없습니다."),

// 건물 노드
BUILDING_NOT_FOUND(404, "유효한 건물을 찾을 수 없습니다."),
;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.softeer5.uniro_backend.common.exception.custom;

import com.softeer5.uniro_backend.common.error.ErrorCode;
import com.softeer5.uniro_backend.common.exception.CustomException;

public class DangerCautionConflictException extends CustomException {
public DangerCautionConflictException(String message, ErrorCode errorCode) {
super(message, errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.softeer5.uniro_backend.common.exception.custom;

import com.softeer5.uniro_backend.common.error.ErrorCode;
import com.softeer5.uniro_backend.common.exception.CustomException;

public class RouteNotFoundException extends CustomException {
public RouteNotFoundException(String message, ErrorCode errorCode) {
super(message, errorCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.softeer5.uniro_backend.common.utils;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.WKTWriter;

import java.util.List;

public final class Utils {
private static final GeometryFactory geometryFactory = new GeometryFactory();

private Utils(){
// 인스턴스화 방지
}
Comment on lines +11 to +16
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오,, 해당 처리 좋네요 ㅎㅎ


public static Point convertDoubleToPoint(double lat, double lng) {
return geometryFactory.createPoint(new Coordinate(lat, lng));
}

public static String convertDoubleToPointWTK(double lat, double lng) {
return String.format("POINT(%f %f)", lat, lng);
}

public static LineString convertDoubleToLineString(List<double[]> co){
if(co==null || co.isEmpty()){
throw new IllegalArgumentException("coordinates can not be null or empty");
}

Coordinate[] coordinates = new Coordinate[co.size()];
for (int i = 0; i < co.size(); i++) {
coordinates[i] = new Coordinate(co.get(i)[0], co.get(i)[1]);
}

return geometryFactory.createLineString(coordinates);
}

public static String convertDoubleToLineStringWTK(List<double[]> co){
LineString lineString = convertDoubleToLineString(co);
WKTWriter writer = new WKTWriter();
return writer.write(lineString);
}

Comment on lines +18 to +44
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 변환로직을 유틸로 만든거 좋은 것 같네요!

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.softeer5.uniro_backend.route.controller;

import com.softeer5.uniro_backend.route.dto.FastestRouteResDTO;
import com.softeer5.uniro_backend.route.dto.GetAllRoutesResDTO;
import com.softeer5.uniro_backend.route.dto.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;

import com.softeer5.uniro_backend.route.dto.GetRiskRoutesResDTO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
Expand All @@ -33,6 +31,26 @@ public interface RouteApi {
})
ResponseEntity<GetRiskRoutesResDTO> getRiskRoutes(@PathVariable("univId") Long univId);

@Operation(summary = "단일 route의 위험&주의 요소 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "단일 route의 위험&주의 요소 조회 성공"),
@ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content),
})
ResponseEntity<GetRiskResDTO> getRisk(@PathVariable("univId") Long univId,
@RequestParam(value = "start-lat") double startLat,
@RequestParam(value = "start-lng") double startLng,
@RequestParam(value = "end-lat") double endLat,
@RequestParam(value = "end-lng") double endLng);

@Operation(summary = "위험&주의 요소 제보")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "단일 route의 위험&주의 요소 제보 성공"),
@ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content),
})
ResponseEntity<Void> updateRisk(@PathVariable("univId") Long univId,
@PathVariable("routeId") Long routeId,
@RequestBody PostRiskReqDTO postRiskReqDTO);

@Operation(summary = "빠른 길 계산")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "빠른 길 계산 성공"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package com.softeer5.uniro_backend.route.controller;

import com.softeer5.uniro_backend.route.dto.FastestRouteResDTO;
import com.softeer5.uniro_backend.route.dto.GetAllRoutesResDTO;
import com.softeer5.uniro_backend.route.dto.*;
import com.softeer5.uniro_backend.route.service.RouteCalculationService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import com.softeer5.uniro_backend.route.dto.GetRiskRoutesResDTO;
import com.softeer5.uniro_backend.route.service.RouteService;

import lombok.RequiredArgsConstructor;
Expand All @@ -26,7 +21,7 @@ public class RouteController implements RouteApi {
@Override
@GetMapping("/{univId}/routes")
public ResponseEntity<List<GetAllRoutesResDTO>> getAllRoutesAndNodes(@PathVariable("univId") Long univId){
List<GetAllRoutesResDTO> allRoutes = routeService.GetAllRoutes(univId);
List<GetAllRoutesResDTO> allRoutes = routeService.getAllRoutes(univId);
return ResponseEntity.ok().body(allRoutes);
}

Expand All @@ -37,11 +32,31 @@ public ResponseEntity<GetRiskRoutesResDTO> getRiskRoutes(@PathVariable("univId")
return ResponseEntity.ok().body(riskRoutes);
}

@Override
@GetMapping("/{univId}/route/risk")
public ResponseEntity<GetRiskResDTO> getRisk(@PathVariable("univId") Long univId,
@RequestParam(value = "start-lat") double startLat,
@RequestParam(value = "start-lng") double startLng,
@RequestParam(value = "end-lat") double endLat,
@RequestParam(value = "end-lng") double endLng){
GetRiskResDTO riskResDTO = routeService.getRisk(univId,startLat,startLng,endLat,endLng);
return ResponseEntity.ok().body(riskResDTO);
}

@Override
@PostMapping("/{univId}/route/risk/{routeId}")
public ResponseEntity<Void> updateRisk (@PathVariable("univId") Long univId,
@PathVariable("routeId") Long routeId,
@RequestBody PostRiskReqDTO postRiskReqDTO){
routeService.updateRisk(univId,routeId,postRiskReqDTO);
return ResponseEntity.ok().build();
}

@Override
@GetMapping("/{univId}/routes/fastest")
public ResponseEntity<FastestRouteResDTO> calculateFastestRoute(@PathVariable("univId") Long univId,
@RequestParam Long startNodeId,
@RequestParam Long endNodeId) {
@RequestParam(value = "start-node-id") Long startNodeId,
@RequestParam(value = "end-node-id") Long endNodeId) {
FastestRouteResDTO fastestRouteResDTO = routeCalculationService.calculateFastestRoute(univId, startNodeId, endNodeId);
return ResponseEntity.ok(fastestRouteResDTO);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.softeer5.uniro_backend.route.dto;

import com.softeer5.uniro_backend.route.entity.CautionType;
import com.softeer5.uniro_backend.route.entity.DangerType;
import com.softeer5.uniro_backend.route.entity.Route;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Getter
@Schema(name = "GetAllRoutesResDTO", description = "특정 간선의 주의/위험요소 조회 DTO")
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class GetRiskResDTO {
@Schema(description = "route ID", example = "3")
private final Long routeId;
@Schema(description = "위험 요소 타입 리스트", example = "[\"SLOPE\", \"STAIRS\"]")
private final List<CautionType> cautionTypes;
@Schema(description = "위험 요소 타입 리스트", example = "[\"SLOPE\", \"STAIRS\"]")
private final List<DangerType> dangerTypes;

public static GetRiskResDTO of(Route route) {
return new GetRiskResDTO(route.getId(),route.getCautionFactorsByList(), route.getDangerFactorsByList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.softeer5.uniro_backend.route.dto;

import com.softeer5.uniro_backend.route.entity.CautionType;
import com.softeer5.uniro_backend.route.entity.DangerType;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
public class PostRiskReqDTO {
private List<CautionType> cautionTypes;
private List<DangerType> dangerTypes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static jakarta.persistence.FetchType.*;

import java.util.List;
import java.util.Set;

import com.softeer5.uniro_backend.resolver.CautionListConverter;
Expand Down Expand Up @@ -59,4 +60,23 @@ public class Route {
@Convert(converter = DangerListConverter.class)
@Column(name = "danger_factors")
private Set<DangerType> dangerFactors;

public List<CautionType> getCautionFactorsByList(){
return cautionFactors.stream().toList();
}

public List<DangerType> getDangerFactorsByList(){
return dangerFactors.stream().toList();
}

public void setCautionFactors(List<CautionType> cautionFactors) {
this.cautionFactors.clear();
this.cautionFactors.addAll(cautionFactors);
}

public void setDangerFactors(List<DangerType> dangerFactors) {
this.dangerFactors.clear();
this.dangerFactors.addAll(dangerFactors);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.softeer5.uniro_backend.route.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -26,4 +27,38 @@ public interface RouteRepository extends JpaRepository<Route, Integer> {
)
List<Route> findRiskRouteByUnivIdWithNode(@Param("univId") Long univId);

@Query(value = """
SELECT r.* FROM route r
JOIN node n1 ON r.node1_id = n1.id
JOIN node n2 ON r.node2_id = n2.id
WHERE r.univ_id = :univId
AND (
(n1.coordinates = ST_SRID(ST_GeomFromText(:point1), 4326)
AND n2.coordinates = ST_SRID(ST_GeomFromText(:point2), 4326))
OR
(n1.coordinates = ST_SRID(ST_GeomFromText(:point2), 4326)
AND n2.coordinates = ST_SRID(ST_GeomFromText(:point1), 4326))
)
""", nativeQuery = true)
Optional<Route> findRouteByPointsAndUnivId(
@Param("univId") Long univId,
@Param("point1") String point1,
@Param("point2") String point2
);

@Query(value = """
SELECT r.* FROM route r
WHERE r.univ_id = :univId
AND (
r.path = ST_SRID(ST_GeomFromText(:path), 4326)
OR
r.path = ST_SRID(ST_GeomFromText(:rev_path), 4326)
)
""", nativeQuery = true)
Optional<Route> findRouteByLineStringAndUnivId(@Param("univId") Long univId,
@Param("path")String path,
@Param("rev_path")String revPath);

Optional<Route> findByIdAndUnivId (Long id, Long univId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

import java.util.List;

import com.softeer5.uniro_backend.route.dto.GetAllRoutesResDTO;
import com.softeer5.uniro_backend.common.error.ErrorCode;
import com.softeer5.uniro_backend.common.exception.custom.DangerCautionConflictException;
import com.softeer5.uniro_backend.common.exception.custom.RouteNotFoundException;
import com.softeer5.uniro_backend.common.utils.Utils;
import com.softeer5.uniro_backend.route.dto.*;
import com.softeer5.uniro_backend.route.entity.CoreRoute;
import com.softeer5.uniro_backend.route.repository.CoreRouteRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.softeer5.uniro_backend.route.dto.GetCautionResDTO;
import com.softeer5.uniro_backend.route.dto.GetDangerResDTO;
import com.softeer5.uniro_backend.route.dto.GetRiskRoutesResDTO;
import com.softeer5.uniro_backend.route.entity.Route;
import com.softeer5.uniro_backend.route.repository.RouteRepository;

Expand All @@ -24,7 +25,7 @@ public class RouteService {
private final CoreRouteRepository coreRouteRepository;


public List<GetAllRoutesResDTO> GetAllRoutes(Long univId) {
public List<GetAllRoutesResDTO> getAllRoutes(Long univId) {
List<CoreRoute> coreRoutes = coreRouteRepository.findByUnivId(univId);
return coreRoutes.stream().map(GetAllRoutesResDTO::of).toList();
}
Expand All @@ -45,7 +46,7 @@ private List<GetDangerResDTO> mapRoutesToDangerDTO(List<Route> routes) {
route.getNode1(),
route.getNode2(),
route.getId(),
route.getDangerFactors().stream().toList()
route.getDangerFactorsByList()
)).toList();
}

Expand All @@ -56,7 +57,48 @@ private List<GetCautionResDTO> mapRoutesToCautionDTO(List<Route> routes) {
route.getNode1(),
route.getNode2(),
route.getId(),
route.getCautionFactors().stream().toList()
route.getCautionFactorsByList()
)).toList();
}


public GetRiskResDTO getRisk(Long univId, double startLat, double startLng, double endLat, double endLng) {
String startWTK = Utils.convertDoubleToPointWTK(startLat, startLng);
String endWTK = Utils.convertDoubleToPointWTK(endLat, endLng);

Route routeWithJoin = routeRepository.findRouteByPointsAndUnivId(univId, startWTK ,endWTK)
.orElseThrow(() -> new RouteNotFoundException("Route Not Found", ErrorCode.ROUTE_NOT_FOUND));

/*
// LineString 사용버전
List<double[]> coordinates = Arrays.asList(
new double[]{startLat, startLng},
new double[]{endLat, endLng}
);
String lineStringWTK = Utils.convertDoubleToLineStringWTK(coordinates);
Collections.reverse(coordinates);
String reverseLineStringWTK = Utils.convertDoubleToLineStringWTK(coordinates);

Route routeWithoutJoin = routeRepository.findRouteByLineStringAndUnivId(univId,lineStringWTK,reverseLineStringWTK)
.orElseThrow(() -> new RouteNotFoundException("Route Not Found", ErrorCode.ROUTE_NOT_FOUND));

*/


return GetRiskResDTO.of(routeWithJoin);
}

@Transactional
public void updateRisk(Long univId, Long routeId, PostRiskReqDTO postRiskReqDTO) {
Route route = routeRepository.findByIdAndUnivId(routeId, univId)
.orElseThrow(() -> new RouteNotFoundException("Route not Found", ErrorCode.ROUTE_NOT_FOUND));

if(!postRiskReqDTO.getCautionTypes().isEmpty() && !postRiskReqDTO.getDangerTypes().isEmpty()){
throw new DangerCautionConflictException("DangerFactors and CautionFactors can't exist simultaneously.",
ErrorCode.CAUTION_DANGER_CANT_EXIST_SIMULTANEOUSLY);
}

route.setCautionFactors(postRiskReqDTO.getCautionTypes());
route.setDangerFactors(postRiskReqDTO.getDangerTypes());
}
}