From ce80277781e6910356d9d1f35786db527f635ce4 Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Wed, 14 Jan 2026 16:43:50 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B6=94=EB=A1=A0=EC=83=81=EC=84=B8=20>=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=EC=A0=95=EB=B3=B4,=20=ED=83=90=EC=A7=80?= =?UTF-8?q?=EB=B3=84=EA=B1=B4=EC=88=98,=20geom=20list=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InferenceResultApiController.java | 60 +++++++ .../inference/dto/InferenceDetailDto.java | 9 + .../service/InferenceResultService.java | 10 ++ .../core/InferenceResultCoreService.java | 10 ++ .../MapSheetLearnRepositoryCustom.java | 7 + .../MapSheetLearnRepositoryImpl.java | 156 ++++++++++++++++++ 6 files changed, 252 insertions(+) diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java index 99fe158d..35391d74 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java @@ -307,4 +307,64 @@ public class InferenceResultApiController { String uuid) { return ApiResponseDto.ok(inferenceResultService.getInferenceResultInfo(uuid)); } + + @Operation(summary = "추론결과 분류별 탐지 건수", description = "추론결과 분류별 탐지 건수") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "검색 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = InferenceDetailDto.AnalResSummary.class))), + @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/infer-class-count") + public ApiResponseDto> getInferenceClassCountList( + @Parameter(description = "회차 uuid", example = "8584e8d4-53b3-4582-bde2-28a81495a626") + @RequestParam + String uuid) { + return ApiResponseDto.ok(inferenceResultService.getInferenceClassCountList(uuid)); + } + + @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-list") + public ApiResponseDto> getInferenceGeomList( + @Parameter(description = "회차 uuid", example = "8584e8d4-53b3-4582-bde2-28a81495a626") + @RequestParam(required = true) + String uuid, + @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) { + InferenceDetailDto.SearchGeoReq searchGeoReq = + new InferenceDetailDto.SearchGeoReq( + targetClass, compareClass, mapSheetNum, page, size, sort); + Page geomList = + inferenceResultService.getInferenceGeomList(uuid, searchGeoReq); + return ApiResponseDto.ok(geomList); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java index cd3a136a..50e51e8f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/dto/InferenceDetailDto.java @@ -294,8 +294,10 @@ public class InferenceDetailDto { @Getter public static class Geom { + UUID uuid; Integer compareYyyy; Integer targetYyyy; + Double cdProb; String classBeforeCd; String classBeforeName; Double classBeforeProb; @@ -303,23 +305,29 @@ public class InferenceDetailDto { String classAfterName; Double classAfterProb; Long mapSheetNum; + String mapSheetName; @JsonIgnore String gemoStr; @JsonIgnore String geomCenterStr; JsonNode gemo; JsonNode geomCenter; public Geom( + UUID uuid, Integer compareYyyy, Integer targetYyyy, + Double cdProb, String classBeforeCd, Double classBeforeProb, String classAfterCd, Double classAfterProb, Long mapSheetNum, + String mapSheetName, String gemoStr, String geomCenterStr) { + this.uuid = uuid; this.compareYyyy = compareYyyy; this.targetYyyy = targetYyyy; + this.cdProb = cdProb; this.classBeforeCd = classBeforeCd; this.classBeforeName = DetectionClassification.fromString(classBeforeCd).getDesc(); this.classBeforeProb = classBeforeProb; @@ -327,6 +335,7 @@ public class InferenceDetailDto { this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc(); this.classAfterProb = classAfterProb; this.mapSheetNum = mapSheetNum; + this.mapSheetName = mapSheetName; this.gemoStr = gemoStr; this.geomCenterStr = geomCenterStr; diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java index 71307c16..9a768285 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java @@ -10,7 +10,9 @@ import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResultInfo; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Detail; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Geom; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.DetectOption; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; @@ -486,4 +488,12 @@ public class InferenceResultService { public AnalResultInfo getInferenceResultInfo(String uuid) { return inferenceResultCoreService.getInferenceResultInfo(uuid); } + + public List getInferenceClassCountList(String uuid) { + return inferenceResultCoreService.getInferenceClassCountList(uuid); + } + + public Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq) { + return inferenceResultCoreService.getInferenceGeomList(uuid, searchGeoReq); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java index b77d7afa..d9956e90 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java @@ -5,8 +5,10 @@ import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResultInfo; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Geom; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.InferenceBatchSheet; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.MapSheet; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.inference.dto.InferenceProgressDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; @@ -388,4 +390,12 @@ public class InferenceResultCoreService { public AnalResultInfo getInferenceResultInfo(String uuid) { return mapSheetLearnRepository.getInferenceResultInfo(uuid); } + + public List getInferenceClassCountList(String uuid) { + return mapSheetLearnRepository.getInferenceClassCountList(uuid); + } + + public Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq) { + return mapSheetLearnRepository.getInferenceGeomList(uuid, searchGeoReq); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java index 5e8ec142..ec5f5eda 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java @@ -1,6 +1,9 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResultInfo; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Geom; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.inference.dto.InferenceProgressDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; @@ -30,4 +33,8 @@ public interface MapSheetLearnRepositoryCustom { Integer getLearnStage(Integer compareYear, Integer targetYear); AnalResultInfo getInferenceResultInfo(String uuid); + + List getInferenceClassCountList(String uuid); + + Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java index 2c471fee..40d5a570 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java @@ -1,24 +1,35 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; import static com.kamco.cd.kamcoback.postgres.entity.QGpuMetricEntity.gpuMetricEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity; import static com.kamco.cd.kamcoback.postgres.entity.QSystemMetricEntity.systemMetricEntity; import com.kamco.cd.kamcoback.common.utils.DateRange; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.AnalResultInfo; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Dashboard; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.Geom; +import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto.SearchGeoReq; import com.kamco.cd.kamcoback.inference.dto.InferenceProgressDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceStatusDetailDto; import com.kamco.cd.kamcoback.model.service.ModelMngService; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; import com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityNotFoundException; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -293,4 +304,149 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto .where(mapSheetLearnEntity.uuid.eq(UUID.fromString(uuid))) .fetchOne(); } + + @Override + public List getInferenceClassCountList(String uuid) { + + // analUid로 분석 정보 조회 + MapSheetAnalInferenceEntity analEntity = + queryFactory + .selectFrom(mapSheetAnalInferenceEntity) + .where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid))) + .fetchOne(); + + if (Objects.isNull(analEntity)) { + throw new EntityNotFoundException("MapSheetAnalInferenceEntity not found for analUid: "); + } + + return queryFactory + .select( + Projections.constructor( + Dashboard.class, + mapSheetAnalSttcEntity.id.classAfterCd, + mapSheetAnalSttcEntity.classAfterCnt.sum())) + .from(mapSheetAnalSttcEntity) + .where(mapSheetAnalSttcEntity.id.analUid.eq(analEntity.getId())) + .groupBy(mapSheetAnalSttcEntity.id.classAfterCd) + .orderBy(mapSheetAnalSttcEntity.id.classAfterCd.asc()) + .fetch(); + } + + /** + * 분석결과 상세 목록 + * + * @param searchGeoReq + * @return + */ + @Override + public Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq) { + Pageable pageable = searchGeoReq.toPageable(); + BooleanBuilder builder = new BooleanBuilder(); + + // analUid로 분석 정보 조회 + MapSheetAnalInferenceEntity analEntity = + queryFactory + .selectFrom(mapSheetAnalInferenceEntity) + .where(mapSheetAnalInferenceEntity.uuid.eq(UUID.fromString(uuid))) + .fetchOne(); + + if (Objects.isNull(analEntity)) { + throw new EntityNotFoundException("MapSheetAnalInferenceEntity not found for analUid: "); + } + + // 추론결과 id + builder.and(mapSheetAnalInferenceEntity.id.eq(analEntity.getId())); + + // 기준년도 분류 + if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) { + builder.and( + mapSheetAnalDataInferenceGeomEntity + .classAfterCd + .toLowerCase() + .eq(searchGeoReq.getTargetClass().toLowerCase())); + } + + // 비교년도 분류 + if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) { + builder.and( + mapSheetAnalDataInferenceGeomEntity + .classBeforeCd + .toLowerCase() + .eq(searchGeoReq.getCompareClass().toLowerCase())); + } + + // 분석도엽 + if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) { + List mapSheetNum = searchGeoReq.getMapSheetNum(); + builder.and(mapSheetAnalDataInferenceGeomEntity.mapSheetNum.in(mapSheetNum)); + } + + List content = + queryFactory + .select( + Projections.constructor( + Geom.class, + mapSheetAnalDataInferenceGeomEntity.uuid, + mapSheetAnalDataInferenceGeomEntity.compareYyyy, + mapSheetAnalDataInferenceGeomEntity.targetYyyy, + mapSheetAnalDataInferenceGeomEntity.cdProb, + mapSheetAnalDataInferenceGeomEntity.classBeforeCd, + mapSheetAnalDataInferenceGeomEntity.classBeforeProb, + mapSheetAnalDataInferenceGeomEntity.classAfterCd, + mapSheetAnalDataInferenceGeomEntity.classAfterProb, + mapSheetAnalDataInferenceGeomEntity.mapSheetNum, + mapInkx5kEntity.mapidNm, + Expressions.stringTemplate( + "ST_AsGeoJSON({0})", mapSheetAnalDataInferenceGeomEntity.geom), + Expressions.stringTemplate( + "ST_AsGeoJSON({0})", mapSheetAnalDataInferenceGeomEntity.geomCenter))) + .from(mapSheetAnalInferenceEntity) + .join(mapSheetAnalDataInferenceGeomEntity) + .on( + mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq( + mapSheetAnalInferenceEntity.compareYyyy), + mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq( + mapSheetAnalInferenceEntity.targetYyyy), + mapSheetAnalDataInferenceGeomEntity.stage.eq(mapSheetAnalInferenceEntity.stage)) + .join(mapInkx5kEntity) + .on( + mapSheetAnalDataInferenceGeomEntity + .mapSheetNum + .stringValue() + .eq(mapInkx5kEntity.mapidcdNo)) + .where(builder) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + long total = + queryFactory + .select(mapSheetAnalDataInferenceGeomEntity.geoUid) + .from(mapSheetAnalInferenceEntity) + .join(mapSheetAnalDataInferenceGeomEntity) + .on( + mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq( + mapSheetAnalInferenceEntity.compareYyyy), + mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq( + mapSheetAnalInferenceEntity.targetYyyy), + mapSheetAnalDataInferenceGeomEntity.stage.eq(mapSheetAnalInferenceEntity.stage)) + .from(mapSheetAnalInferenceEntity) + .join(mapSheetAnalDataInferenceGeomEntity) + .on( + mapSheetAnalDataInferenceGeomEntity.compareYyyy.eq( + mapSheetAnalInferenceEntity.compareYyyy), + mapSheetAnalDataInferenceGeomEntity.targetYyyy.eq( + mapSheetAnalInferenceEntity.targetYyyy), + mapSheetAnalDataInferenceGeomEntity.stage.eq(mapSheetAnalInferenceEntity.stage)) + .join(mapInkx5kEntity) + .on( + mapSheetAnalDataInferenceGeomEntity + .mapSheetNum + .stringValue() + .eq(mapInkx5kEntity.mapidcdNo)) + .where(builder) + .fetchCount(); + + return new PageImpl<>(content, pageable, total); + } }