package com.kamco.cd.kamcoback.inference; import com.kamco.cd.kamcoback.config.api.ApiResponseDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.LearningModelResultDto; import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import com.kamco.cd.kamcoback.inference.service.LearningModelResultProcessor; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; 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 java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Tag(name = "추론관리 분석결과", description = "추론관리 분석결과") @RequestMapping({"/api/inf/res"}) @RequiredArgsConstructor @RestController public class InferenceResultApiController { private static final Logger logger = LoggerFactory.getLogger(InferenceResultApiController.class); private final InferenceResultService inferenceResultService; private final LearningModelResultProcessor learningModelResultProcessor; @Operation(summary = "추론관리 분석결과 목록 조회", description = "분석상태, 제목으로 분석결과를 조회 합니다.") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "검색 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = Page.class))), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/list") public ApiResponseDto> getInferenceResultList( @Parameter(description = "분석상태", example = "0002") @RequestParam(required = false) String statCode, @Parameter(description = "제목", example = "변화탐지") @RequestParam(required = false) String title, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") int size) { InferenceResultDto.SearchReq searchReq = new InferenceResultDto.SearchReq(statCode, title, page, size); Page analResList = inferenceResultService.getInferenceResultList(searchReq); return ApiResponseDto.ok(analResList); } @Operation(summary = "추론관리 분석결과 요약정보", description = "분석결과 요약정보를 조회합니다.") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "검색 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = InferenceResultDto.AnalResSummary.class))), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/summary/{id}") public ApiResponseDto getInferenceResultSummary( @Parameter(description = "목록 id", example = "1") @PathVariable Long id) { return ApiResponseDto.ok(inferenceResultService.getInferenceResultSummary(id)); } @Operation(summary = "추론관리 분석결과 상세", description = "분석결과 상제 정보 Summary, DashBoard") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "검색 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = InferenceResultDto.Detail.class))), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/detail/{id}") public ApiResponseDto getInferenceDetail( @Parameter(description = "목록 id", example = "1") @PathVariable Long id) { return ApiResponseDto.ok(inferenceResultService.getDetail(id)); } @Operation(summary = "추론관리 분석결과 상세 목록", description = "추론관리 분석결과 상세 목록 geojson 데이터 조회") @ApiResponses( value = { @ApiResponse( responseCode = "200", description = "검색 성공", content = @Content( mediaType = "application/json", schema = @Schema(implementation = Page.class))), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @GetMapping("/geom/{id}") public ApiResponseDto> getInferenceResultGeomList( @Parameter(description = "분석결과 id", example = "1") @PathVariable Long id, @Parameter(description = "기준년도 분류", example = "land") @RequestParam(required = false) String targetClass, @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false) String compareClass, @Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false) List mapSheetNum, @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") int size, @Parameter(description = "정렬 조건 (형식: 필드명,방향)", example = "name,asc") @RequestParam(required = false) String sort) { InferenceResultDto.SearchGeoReq searchGeoReq = new InferenceResultDto.SearchGeoReq( targetClass, compareClass, mapSheetNum, page, size, sort); Page geomList = inferenceResultService.getInferenceResultGeomList(id, searchGeoReq); return ApiResponseDto.ok(geomList); } // @Operation(summary = "학습모델 결과 처리", description = "실제 학습모델 GeoJSON 파일을 처리하여 데이터베이스에 저장합니다.") // @ApiResponses( // value = { // @ApiResponse( // responseCode = "200", // description = "처리 성공", // content = // @Content( // mediaType = "application/json", // schema = // @Schema(implementation = // LearningModelResultDto.ProcessResponse.class))), // @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content), // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) // }) // @PostMapping("/learning-model/process") public ApiResponseDto processLearningModelResult( @RequestBody LearningModelResultDto.ProcessRequest request) { try { logger.info("Processing learning model result file: {}", request.getFilePath()); Path filePath = Paths.get(request.getFilePath()); int processedFeatures = learningModelResultProcessor.processLearningModelResult(filePath); LearningModelResultDto.ProcessResponse response = LearningModelResultDto.ProcessResponse.builder() .success(true) .message("학습모델 결과 처리가 완료되었습니다.") .processedFeatures(processedFeatures) .filePath(request.getFilePath()) .build(); logger.info( "Successfully processed {} features from file: {}", processedFeatures, request.getFilePath()); return ApiResponseDto.ok(response); } catch (Exception e) { logger.error("Failed to process learning model result: {}", request.getFilePath(), e); LearningModelResultDto.ProcessResponse response = LearningModelResultDto.ProcessResponse.builder() .success(false) .message("학습모델 결과 처리 중 오류가 발생했습니다: " + e.getMessage()) .processedFeatures(0) .filePath(request.getFilePath()) .build(); return ApiResponseDto.ok(response); } } // @Operation(summary = "학습모델 결과 일괄 처리", description = "여러 학습모델 GeoJSON 파일을 일괄 처리하여 데이터베이스에 // 저장합니다.") // @ApiResponses( // value = { // @ApiResponse( // responseCode = "200", // description = "처리 성공", // content = // @Content( // mediaType = "application/json", // schema = // @Schema( // implementation = // LearningModelResultDto.BatchProcessResponse.class))), // @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content), // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) // }) // @PostMapping("/learning-model/process-batch") public ApiResponseDto processBatchLearningModelResults( @RequestBody LearningModelResultDto.BatchProcessRequest request) { try { logger.info("Processing {} learning model result files", request.getFilePaths().size()); List filePaths = new ArrayList<>(); for (String filePath : request.getFilePaths()) { filePaths.add(Paths.get(filePath)); } int totalProcessedFeatures = learningModelResultProcessor.processMultipleLearningModelResults(filePaths); LearningModelResultDto.BatchProcessResponse response = LearningModelResultDto.BatchProcessResponse.builder() .success(true) .message("일괄 학습모델 결과 처리가 완료되었습니다.") .totalProcessedFeatures(totalProcessedFeatures) .processedFileCount(request.getFilePaths().size()) .filePaths(request.getFilePaths()) .build(); logger.info( "Successfully processed {} features from {} files", totalProcessedFeatures, request.getFilePaths().size()); return ApiResponseDto.ok(response); } catch (Exception e) { logger.error("Failed to process batch learning model results", e); LearningModelResultDto.BatchProcessResponse response = LearningModelResultDto.BatchProcessResponse.builder() .success(false) .message("일괄 학습모델 결과 처리 중 오류가 발생했습니다: " + e.getMessage()) .totalProcessedFeatures(0) .processedFileCount(0) .filePaths(request.getFilePaths()) .build(); return ApiResponseDto.ok(response); } } // @Operation(summary = "기본 학습모델 파일 처리", description = "미리 준비된 학습모델 파일을 처리합니다.") // @ApiResponses( // value = { // @ApiResponse( // responseCode = "200", // description = "처리 성공", // content = // @Content( // mediaType = "application/json", // schema = // @Schema( // implementation = // LearningModelResultDto.BatchProcessResponse.class))), // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) // }) // @PostMapping("/learning-model/process-default") public ApiResponseDto processDefaultLearningModelResults() { try { logger.info("Processing default learning model result files"); // Process the two default learning model files from upload directory List defaultFilePaths = List.of( "/Users/deniallee/geojson/upload/캠코_2021_2022_35813023.geojson", "/Users/deniallee/geojson/upload/캠코_2023_2024_35810049.geojson"); List filePaths = new ArrayList<>(); for (String filePath : defaultFilePaths) { filePaths.add(Paths.get(filePath)); } int totalProcessedFeatures = learningModelResultProcessor.processMultipleLearningModelResults(filePaths); LearningModelResultDto.BatchProcessResponse response = LearningModelResultDto.BatchProcessResponse.builder() .success(true) .message("기본 학습모델 결과 파일 처리가 완료되었습니다.") .totalProcessedFeatures(totalProcessedFeatures) .processedFileCount(defaultFilePaths.size()) .filePaths(defaultFilePaths) .build(); logger.info( "Successfully processed {} features from {} default files", totalProcessedFeatures, defaultFilePaths.size()); return ApiResponseDto.ok(response); } catch (Exception e) { logger.error("Failed to process default learning model results", e); LearningModelResultDto.BatchProcessResponse response = LearningModelResultDto.BatchProcessResponse.builder() .success(false) .message("기본 학습모델 결과 처리 중 오류가 발생했습니다: " + e.getMessage()) .totalProcessedFeatures(0) .processedFileCount(0) .filePaths(List.of()) .build(); return ApiResponseDto.ok(response); } } }