추론관리 api 수정, 분석된 도엽 목록 추가

This commit is contained in:
2025-11-28 16:33:20 +09:00
parent 4cb41c92cd
commit 4333350012
15 changed files with 285 additions and 301 deletions

View File

@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
@Tag(name = "공통코드 관리", description = "공통코드 관리 API") @Tag(name = "공통코드 관리", description = "공통코드 관리 API")
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@RequestMapping("/api/code") @RequestMapping({"/demo/code", "/api/code"})
public class CommonCodeApiController { public class CommonCodeApiController {
private final CommonCodeService commonCodeService; private final CommonCodeService commonCodeService;

View File

@@ -1,13 +1,48 @@
package com.kamco.cd.kamcoback.common.api; package com.kamco.cd.kamcoback.common.api;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.inference.dto.LearningModelResultDto;
import com.kamco.cd.kamcoback.inference.service.InferenceResultService;
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.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Tag(name = "공통", description = "공통")
@RestController @RestController
@RequestMapping("/api/common") @RequiredArgsConstructor
@RequestMapping({"/demo/common", "/api/common"})
public class CommonController { public class CommonController {
private final InferenceResultService inferenceResultService;
@Operation(summary = "추론된 도엽 목록", description = "추론된 도엽 목록 5000:1")
@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)
})
@GetMapping("/sheets/{id}") @GetMapping("/sheets/{id}")
public void getSheetList() {} public ApiResponseDto<List<String>> getSheets(
@Parameter(description = "분석결과 id", example = "1") @PathVariable Long id) {
return ApiResponseDto.ok(inferenceResultService.getSheets(id));
}
} }

View File

@@ -1,44 +0,0 @@
package com.kamco.cd.kamcoback.common.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum DetectionClassification {
BUILDING("building", "빌딩"),
CONTAINER("container", "컨테이너(창고·적재함)"),
FIELD("field", "경작지 / 들판"),
FOREST("forest", ""),
GRASS("grass", "초지 / 잔디지역"),
GREENHOUSE("greenhouse", "비닐하우스"),
LAND("land", "나지"),
ORCHARD("orchard", "과수원"),
ROAD("road", "도로"),
STONE("stone", "암석 / 돌 지역"),
TANK("tank", "탱크(저유탱크 등 저장시설)"),
TUMULUS("tumulus", "고분(무덤)"),
WASTE("waste", "폐기물 적치장 / 황폐지"),
WATER("water", "수체(水域) / 물"),
ETC("ETC", "기타"); // For 'etc' (miscellaneous/other)
private final String id;
private final String desc;
/**
* Optional: Helper method to get the enum from a String, case-insensitive, or return ETC if not
* found.
*/
public static DetectionClassification fromString(String text) {
if (text == null || text.trim().isEmpty()) {
return ETC;
}
try {
return DetectionClassification.valueOf(text.toUpperCase());
} catch (IllegalArgumentException e) {
// If the string doesn't match any enum constant name, return ETC
return ETC;
}
}
}

View File

@@ -62,17 +62,19 @@ public class GeometryConversionService {
try { try {
// 기존 geometry 데이터 확인 - 데이터가 이미 존재하고 유효한 경우 재처리 건너뛰기 // 기존 geometry 데이터 확인 - 데이터가 이미 존재하고 유효한 경우 재처리 건너뛰기
List<MapSheetLearnDataGeomEntity> existingGeoms = mapSheetLearnDataGeomRepository.findByDataUid(learnData.getId()); List<MapSheetLearnDataGeomEntity> existingGeoms =
mapSheetLearnDataGeomRepository.findByDataUid(learnData.getId());
if (!existingGeoms.isEmpty() && isValidGeometryData(existingGeoms)) { if (!existingGeoms.isEmpty() && isValidGeometryData(existingGeoms)) {
log.debug("유효한 geometry 데이터가 이미 존재합니다. 재처리를 건너뜁니다: {}", learnData.getId()); log.debug("유효한 geometry 데이터가 이미 존재합니다. 재처리를 건너뜁니다: {}", learnData.getId());
return existingGeoms.stream().map(MapSheetLearnDataGeomEntity::getId).toList(); return existingGeoms.stream().map(MapSheetLearnDataGeomEntity::getId).toList();
} }
// 유효하지 않은 데이터만 조건부 삭제 (null geometry 또는 잘못된 형식) // 유효하지 않은 데이터만 조건부 삭제 (null geometry 또는 잘못된 형식)
if (!existingGeoms.isEmpty()) { if (!existingGeoms.isEmpty()) {
List<MapSheetLearnDataGeomEntity> invalidGeoms = existingGeoms.stream() List<MapSheetLearnDataGeomEntity> invalidGeoms =
.filter(g -> g.getGeom() == null || g.getGeom().isEmpty()) existingGeoms.stream()
.toList(); .filter(g -> g.getGeom() == null || g.getGeom().isEmpty())
.toList();
if (!invalidGeoms.isEmpty()) { if (!invalidGeoms.isEmpty()) {
mapSheetLearnDataGeomRepository.deleteAll(invalidGeoms); mapSheetLearnDataGeomRepository.deleteAll(invalidGeoms);
log.debug("유효하지 않은 geometry 데이터만 삭제했습니다: {}개", invalidGeoms.size()); log.debug("유효하지 않은 geometry 데이터만 삭제했습니다: {}개", invalidGeoms.size());
@@ -454,7 +456,7 @@ public class GeometryConversionService {
if (geometryEntities == null || geometryEntities.isEmpty()) { if (geometryEntities == null || geometryEntities.isEmpty()) {
return false; return false;
} }
// 모든 geometry가 null이 아니고 유효한지 확인 // 모든 geometry가 null이 아니고 유효한지 확인
return geometryEntities.stream() return geometryEntities.stream()
.allMatch(entity -> entity.getGeom() != null && !entity.getGeom().isEmpty()); .allMatch(entity -> entity.getGeom() != null && !entity.getGeom().isEmpty());

View File

@@ -21,6 +21,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,7 +29,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Tag(name = "추론관리 분석결과", description = "추론관리 분석결과") @Tag(name = "추론관리 분석결과", description = "추론관리 분석결과")
@RequestMapping("/api/inf/res") @RequestMapping({"/demo/inf/res", "/api/inf/res"})
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
public class InferenceResultApiController { public class InferenceResultApiController {
@@ -53,10 +54,9 @@ public class InferenceResultApiController {
}) })
@GetMapping("/list") @GetMapping("/list")
public ApiResponseDto<Page<InferenceResultDto.AnalResList>> getInferenceResultList( public ApiResponseDto<Page<InferenceResultDto.AnalResList>> getInferenceResultList(
@Parameter(description = "분석상태", example = "0000") @RequestParam(required = false) @Parameter(description = "분석상태", example = "0002") @RequestParam(required = false)
String statCode, String statCode,
@Parameter(description = "제목", example = "2023_2024년도") @RequestParam(required = false) @Parameter(description = "제목", example = "변화탐지") @RequestParam(required = false) String title,
String title,
@Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0") @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0")
int page, int page,
@Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20") @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20")
@@ -84,9 +84,9 @@ public class InferenceResultApiController {
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/summary") @GetMapping("/summary/{id}")
public ApiResponseDto<InferenceResultDto.AnalResSummary> getInferenceResultSummary( public ApiResponseDto<InferenceResultDto.AnalResSummary> getInferenceResultSummary(
@Parameter(description = "목록 id", example = "1") @RequestParam Long id) { @Parameter(description = "목록 id", example = "1") @PathVariable Long id) {
return ApiResponseDto.ok(inferenceResultService.getInferenceResultSummary(id)); return ApiResponseDto.ok(inferenceResultService.getInferenceResultSummary(id));
} }
@@ -122,11 +122,12 @@ public class InferenceResultApiController {
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/geom") @GetMapping("/geom/{id}")
public ApiResponseDto<Page<InferenceResultDto.Geom>> getInferenceResultGeomList( public ApiResponseDto<Page<InferenceResultDto.Geom>> getInferenceResultGeomList(
@Parameter(description = "기준년도 분류", example = "0001") @RequestParam(required = false) @Parameter(description = "분석결과 id", example = "1") @PathVariable Long id,
@Parameter(description = "기준년도 분류", example = "land") @RequestParam(required = false)
String targetClass, String targetClass,
@Parameter(description = "비교년도 분류", example = "0002") @RequestParam(required = false) @Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false)
String compareClass, String compareClass,
@Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false) @Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false)
List<Long> mapSheetNum, List<Long> mapSheetNum,
@@ -141,7 +142,7 @@ public class InferenceResultApiController {
new InferenceResultDto.SearchGeoReq( new InferenceResultDto.SearchGeoReq(
targetClass, compareClass, mapSheetNum, page, size, sort); targetClass, compareClass, mapSheetNum, page, size, sort);
Page<InferenceResultDto.Geom> geomList = Page<InferenceResultDto.Geom> geomList =
inferenceResultService.getInferenceResultGeomList(searchGeoReq); inferenceResultService.getInferenceResultGeomList(id, searchGeoReq);
return ApiResponseDto.ok(geomList); return ApiResponseDto.ok(geomList);
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.inference.dto; package com.kamco.cd.kamcoback.inference.dto;
import com.kamco.cd.kamcoback.common.enums.DetectionClassification;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
@@ -8,6 +9,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import org.locationtech.jts.geom.Geometry;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@@ -50,6 +52,7 @@ public class InferenceResultDto {
@Schema(name = "AnalysisResultList", description = "분석결과 목록") @Schema(name = "AnalysisResultList", description = "분석결과 목록")
@Getter @Getter
public static class AnalResList { public static class AnalResList {
private Long id; private Long id;
private String analTitle; private String analTitle;
private String analMapSheet; private String analMapSheet;
@@ -91,6 +94,7 @@ public class InferenceResultDto {
@Schema(name = "AnalysisResultSummary", description = "분석결과 요약정보") @Schema(name = "AnalysisResultSummary", description = "분석결과 요약정보")
@Getter @Getter
public static class AnalResSummary { public static class AnalResSummary {
private Long id; private Long id;
private String analTitle; private String analTitle;
private String modelInfo; private String modelInfo;
@@ -143,6 +147,7 @@ public class InferenceResultDto {
@Getter @Getter
public static class Dashboard { public static class Dashboard {
Integer compareYyyy; Integer compareYyyy;
Integer targetYyyy; Integer targetYyyy;
Long mapSheetNum; Long mapSheetNum;
@@ -189,19 +194,17 @@ public class InferenceResultDto {
@Getter @Getter
public static class Detail { public static class Detail {
AnalResSummary summary;
List<Dashboard> dashboard;
Long totalCnt;
public Detail(AnalResSummary summary, List<Dashboard> dashboard, Long totalCnt) { AnalResSummary summary;
public Detail(AnalResSummary summary) {
this.summary = summary; this.summary = summary;
this.dashboard = dashboard;
this.totalCnt = totalCnt;
} }
} }
@Getter @Getter
public static class Geom { public static class Geom {
Integer compareYyyy; Integer compareYyyy;
Integer targetYyyy; Integer targetYyyy;
String classBeforeCd; String classBeforeCd;
@@ -211,26 +214,30 @@ public class InferenceResultDto {
String classAfterName; String classAfterName;
Double classAfterProb; Double classAfterProb;
Long mapSheetNum; Long mapSheetNum;
Geometry gemo;
Geometry geomCenter;
public Geom( public Geom(
Integer compareYyyy, Integer compareYyyy,
Integer targetYyyy, Integer targetYyyy,
String classBeforeCd, String classBeforeCd,
String classBeforeName,
Double classBeforeProb, Double classBeforeProb,
String classAfterCd, String classAfterCd,
String classAfterName,
Double classAfterProb, Double classAfterProb,
Long mapSheetNum) { Long mapSheetNum,
Geometry gemo,
Geometry geomCenter) {
this.compareYyyy = compareYyyy; this.compareYyyy = compareYyyy;
this.targetYyyy = targetYyyy; this.targetYyyy = targetYyyy;
this.classBeforeCd = classBeforeCd; this.classBeforeCd = classBeforeCd;
this.classBeforeName = classBeforeName; this.classBeforeName = DetectionClassification.fromString(classBeforeCd).getDesc();
this.classBeforeProb = classBeforeProb; this.classBeforeProb = classBeforeProb;
this.classAfterCd = classAfterCd; this.classAfterCd = classAfterCd;
this.classAfterName = classAfterName; this.classAfterName = DetectionClassification.fromString(classAfterCd).getDesc();
this.classAfterProb = classAfterProb; this.classAfterProb = classAfterProb;
this.mapSheetNum = mapSheetNum; this.mapSheetNum = mapSheetNum;
this.gemo = gemo;
this.geomCenter = geomCenter;
} }
} }

View File

@@ -1,7 +1,6 @@
package com.kamco.cd.kamcoback.inference.service; package com.kamco.cd.kamcoback.inference.service;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Detail; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Detail;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService; import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService;
import java.util.List; import java.util.List;
@@ -38,16 +37,6 @@ public class InferenceResultService {
return inferenceResultCoreService.getInferenceResultSummary(id); return inferenceResultCoreService.getInferenceResultSummary(id);
} }
/**
* 분석결과 대시보드 조회
*
* @param id
* @return
*/
public List<Dashboard> getInferenceResultBasic(Long id) {
return inferenceResultCoreService.getInferenceResultDashboard(id);
}
/** /**
* 분석결과 상세 목록 * 분석결과 상세 목록
* *
@@ -55,8 +44,8 @@ public class InferenceResultService {
* @return * @return
*/ */
public Page<InferenceResultDto.Geom> getInferenceResultGeomList( public Page<InferenceResultDto.Geom> getInferenceResultGeomList(
InferenceResultDto.SearchGeoReq searchGeoReq) { Long id, InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultCoreService.getInferenceResultGeomList(searchGeoReq); return inferenceResultCoreService.getInferenceResultGeomList(id, searchGeoReq);
} }
/** /**
@@ -68,11 +57,16 @@ public class InferenceResultService {
public Detail getDetail(Long id) { public Detail getDetail(Long id) {
// summary // summary
InferenceResultDto.AnalResSummary summary = this.getInferenceResultSummary(id); InferenceResultDto.AnalResSummary summary = this.getInferenceResultSummary(id);
// 탐지건수 dashBoard return new Detail(summary);
List<InferenceResultDto.Dashboard> dashboardList = this.getInferenceResultBasic(id); }
// 전체 탐지건수
Long totalCnt = dashboardList.stream().mapToLong(Dashboard::getClassAfterCnt).sum();
return new Detail(summary, dashboardList, totalCnt); /**
* 추론된 5000:1 도엽 목록
*
* @param id
* @return
*/
public List<String> getSheets(Long id) {
return inferenceResultCoreService.getSheets(id).stream().map(String::valueOf).toList();
} }
} }

View File

@@ -1,7 +1,6 @@
package com.kamco.cd.kamcoback.postgres.core; package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Dashboard;
import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository; import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository;
import jakarta.persistence.EntityNotFoundException; import jakarta.persistence.EntityNotFoundException;
import java.util.List; import java.util.List;
@@ -22,7 +21,7 @@ public class InferenceResultCoreService {
* @return * @return
*/ */
public Page<InferenceResultDto.AnalResList> getInferenceResultList( public Page<InferenceResultDto.AnalResList> getInferenceResultList(
InferenceResultDto.SearchReq searchReq) { InferenceResultDto.SearchReq searchReq) {
return inferenceResultRepository.getInferenceResultList(searchReq); return inferenceResultRepository.getInferenceResultList(searchReq);
} }
@@ -34,25 +33,12 @@ public class InferenceResultCoreService {
*/ */
public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) { public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) {
InferenceResultDto.AnalResSummary summary = InferenceResultDto.AnalResSummary summary =
inferenceResultRepository inferenceResultRepository
.getInferenceResultSummary(id) .getInferenceResultSummary(id)
.orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id)); .orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id));
return summary; return summary;
} }
/**
* 분석결과 대시보드 조회
*
* @param id
* @return
*/
public List<Dashboard> getInferenceResultDashboard(Long id) {
return null;
// inferenceResultRepository.getInferenceResultDashboard(id).stream()
// .map(MapSheetAnalSttcEntity::toDto)
// .toList();
}
/** /**
* 분석결과 상세 목록 * 분석결과 상세 목록
* *
@@ -60,12 +46,17 @@ public class InferenceResultCoreService {
* @return * @return
*/ */
public Page<InferenceResultDto.Geom> getInferenceResultGeomList( public Page<InferenceResultDto.Geom> getInferenceResultGeomList(
InferenceResultDto.SearchGeoReq searchGeoReq) { Long id, InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultRepository.getInferenceGeomList(searchGeoReq); return inferenceResultRepository.getInferenceGeomList(id, searchGeoReq);
}
/**
* 추론된 5000:1 도엽 목록
*
* @param id
* @return
*/
public List<Long> getSheets(Long id) {
return inferenceResultRepository.getSheets(id);
} }
//
// public List<Long> getSheets(
// return inferenceResultRepository.get
//
// }
} }

View File

@@ -21,8 +21,13 @@ import org.locationtech.jts.geom.Geometry;
public class MapSheetAnalDataGeomEntity { public class MapSheetAnalDataGeomEntity {
@Id @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_sheet_anal_data_geom_id_gen") @GeneratedValue(
@SequenceGenerator(name = "tb_map_sheet_anal_data_geom_id_gen", sequenceName = "tb_map_sheet_learn_data_geom_geom_uid", allocationSize = 1) strategy = GenerationType.SEQUENCE,
generator = "tb_map_sheet_anal_data_geom_id_gen")
@SequenceGenerator(
name = "tb_map_sheet_anal_data_geom_id_gen",
sequenceName = "tb_map_sheet_learn_data_geom_geom_uid",
allocationSize = 1)
@Column(name = "geo_uid", nullable = false) @Column(name = "geo_uid", nullable = false)
private Long id; private Long id;
@@ -119,6 +124,7 @@ public class MapSheetAnalDataGeomEntity {
@Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE) @Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
private String fitStateCmmnt; private String fitStateCmmnt;
@Column(name = "ref_map_sheet_num") @Column(name = "ref_map_sheet_num")
private Long refMapSheetNum; private Long refMapSheetNum;
@@ -127,6 +133,4 @@ public class MapSheetAnalDataGeomEntity {
@Column(name = "geom_center", columnDefinition = "geometry") @Column(name = "geom_center", columnDefinition = "geometry")
private Geometry geomCenter; private Geometry geomCenter;
} }

View File

@@ -6,7 +6,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import java.time.OffsetDateTime; import java.time.ZonedDateTime;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.ColumnDefault;
@@ -17,8 +17,7 @@ import org.hibernate.annotations.ColumnDefault;
@Table(name = "tb_map_sheet_anal_sttc") @Table(name = "tb_map_sheet_anal_sttc")
public class MapSheetAnalSttcEntity { public class MapSheetAnalSttcEntity {
@EmbeddedId @EmbeddedId private MapSheetAnalSttcEntityId id;
private MapSheetAnalSttcEntityId id;
@ColumnDefault("0") @ColumnDefault("0")
@Column(name = "class_before_cnt") @Column(name = "class_before_cnt")
@@ -30,14 +29,14 @@ public class MapSheetAnalSttcEntity {
@ColumnDefault("now()") @ColumnDefault("now()")
@Column(name = "created_dttm") @Column(name = "created_dttm")
private OffsetDateTime createdDttm; private ZonedDateTime createdDttm;
@Column(name = "created_uid") @Column(name = "created_uid")
private Long createdUid; private Long createdUid;
@ColumnDefault("now()") @ColumnDefault("now()")
@Column(name = "updated_dttm") @Column(name = "updated_dttm")
private OffsetDateTime updatedDttm; private ZonedDateTime updatedDttm;
@Column(name = "updated_uid") @Column(name = "updated_uid")
private Long updatedUid; private Long updatedUid;
@@ -57,5 +56,4 @@ public class MapSheetAnalSttcEntity {
@Size(max = 30) @Size(max = 30)
@Column(name = "class_after_cd", length = 30) @Column(name = "class_after_cd", length = 30)
private String classAfterCd; private String classAfterCd;
} }

View File

@@ -15,6 +15,7 @@ import org.hibernate.Hibernate;
public class MapSheetAnalSttcEntityId implements Serializable { public class MapSheetAnalSttcEntityId implements Serializable {
private static final long serialVersionUID = 2285491656408229553L; private static final long serialVersionUID = 2285491656408229553L;
@NotNull @NotNull
@Column(name = "compare_yyyy", nullable = false) @Column(name = "compare_yyyy", nullable = false)
private Integer compareYyyy; private Integer compareYyyy;
@@ -36,14 +37,13 @@ public class MapSheetAnalSttcEntityId implements Serializable {
return false; return false;
} }
MapSheetAnalSttcEntityId entity = (MapSheetAnalSttcEntityId) o; MapSheetAnalSttcEntityId entity = (MapSheetAnalSttcEntityId) o;
return Objects.equals(this.targetYyyy, entity.targetYyyy) && return Objects.equals(this.targetYyyy, entity.targetYyyy)
Objects.equals(this.compareYyyy, entity.compareYyyy) && && Objects.equals(this.compareYyyy, entity.compareYyyy)
Objects.equals(this.mapSheetNum, entity.mapSheetNum); && Objects.equals(this.mapSheetNum, entity.mapSheetNum);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(targetYyyy, compareYyyy, mapSheetNum); return Objects.hash(targetYyyy, compareYyyy, mapSheetNum);
} }
} }

View File

@@ -1,7 +1,6 @@
package com.kamco.cd.kamcoback.postgres.repository.Inference; package com.kamco.cd.kamcoback.postgres.repository.Inference;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalSttcEntity;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -9,13 +8,12 @@ import org.springframework.data.domain.Page;
public interface InferenceResultRepositoryCustom { public interface InferenceResultRepositoryCustom {
Page<InferenceResultDto.AnalResList> getInferenceResultList( Page<InferenceResultDto.AnalResList> getInferenceResultList(
InferenceResultDto.SearchReq searchReq); InferenceResultDto.SearchReq searchReq);
Optional<InferenceResultDto.AnalResSummary> getInferenceResultSummary(Long id); Optional<InferenceResultDto.AnalResSummary> getInferenceResultSummary(Long id);
List<MapSheetAnalSttcEntity> getInferenceResultDashboard(Long id); Page<InferenceResultDto.Geom> getInferenceGeomList(
Long id, InferenceResultDto.SearchGeoReq searchGeoReq);
Page<InferenceResultDto.Geom> getInferenceGeomList(InferenceResultDto.SearchGeoReq searchGeoReq);
List<Long> getSheets(Long id); List<Long> getSheets(Long id);
} }

View File

@@ -2,11 +2,9 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.SearchGeoReq;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalSttcEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalSttcEntity;
import com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity; import com.kamco.cd.kamcoback.postgres.entity.QModelMngEntity;
import com.kamco.cd.kamcoback.postgres.entity.QModelVerEntity; import com.kamco.cd.kamcoback.postgres.entity.QModelVerEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
@@ -30,12 +28,11 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
private final QModelMngEntity tmm = QModelMngEntity.modelMngEntity; private final QModelMngEntity tmm = QModelMngEntity.modelMngEntity;
private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity; private final QModelVerEntity tmv = QModelVerEntity.modelVerEntity;
private final QMapSheetAnalEntity mapSheetAnal = QMapSheetAnalEntity.mapSheetAnalEntity; private final QMapSheetAnalEntity mapSheetAnalEntity = QMapSheetAnalEntity.mapSheetAnalEntity;
private final QMapSheetAnalDataEntity mapSheetAnalEntity = QMapSheetAnalDataEntity.mapSheetAnalDataEntity; private final QMapSheetAnalDataEntity mapSheetAnalDataEntity =
private final QMapSheetAnalSttcEntity mapSheetAnalSttc = QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity; private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeomEntity =
private final QMapSheetAnalDataGeomEntity mapSheetAnalDataGeom = QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
/** /**
* 분석결과 목록 조회 * 분석결과 목록 조회
@@ -45,45 +42,49 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
*/ */
@Override @Override
public Page<InferenceResultDto.AnalResList> getInferenceResultList( public Page<InferenceResultDto.AnalResList> getInferenceResultList(
InferenceResultDto.SearchReq searchReq) { InferenceResultDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable(); Pageable pageable = searchReq.toPageable();
// "0000" 전체조회 // "0000" 전체조회
BooleanBuilder builder = new BooleanBuilder(); BooleanBuilder builder = new BooleanBuilder();
if (searchReq.getStatCode() != null && !"0000".equals(searchReq.getStatCode())) { if (searchReq.getStatCode() != null && !"0000".equals(searchReq.getStatCode())) {
builder.and(mapSheetAnal.analState.eq(searchReq.getStatCode())); builder.and(mapSheetAnalEntity.analState.eq(searchReq.getStatCode()));
} }
// 제목 // 제목
if (searchReq.getTitle() != null) { if (searchReq.getTitle() != null) {
builder.and(mapSheetAnal.analTitle.like("%" + searchReq.getTitle() + "%")); builder.and(mapSheetAnalEntity.analTitle.like("%" + searchReq.getTitle() + "%"));
} }
List<InferenceResultDto.AnalResList> content = List<InferenceResultDto.AnalResList> content =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
InferenceResultDto.AnalResList.class, InferenceResultDto.AnalResList.class,
mapSheetAnal.id, mapSheetAnalEntity.id,
mapSheetAnal.analTitle, mapSheetAnalEntity.analTitle,
mapSheetAnal.analMapSheet, mapSheetAnalEntity.analMapSheet,
mapSheetAnal.detectingCnt, mapSheetAnalEntity.detectingCnt,
mapSheetAnal.analStrtDttm, mapSheetAnalEntity.analStrtDttm,
mapSheetAnal.analEndDttm, mapSheetAnalEntity.analEndDttm,
mapSheetAnal.analSec, mapSheetAnalEntity.analSec,
mapSheetAnal.analPredSec, mapSheetAnalEntity.analPredSec,
mapSheetAnal.analState, mapSheetAnalEntity.analState,
Expressions.stringTemplate( Expressions.stringTemplate(
"fn_code_name({0}, {1})", "0002", mapSheetAnal.analState), "fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState),
mapSheetAnal.gukyuinUsed)) mapSheetAnalEntity.gukyuinUsed))
.from(mapSheetAnal) .from(mapSheetAnalEntity)
.where(builder) .where(builder)
.offset(pageable.getOffset()) .offset(pageable.getOffset())
.limit(pageable.getPageSize()) .limit(pageable.getPageSize())
.orderBy(mapSheetAnal.createdDttm.desc()) .orderBy(mapSheetAnalEntity.createdDttm.desc())
.fetch(); .fetch();
long total = long total =
queryFactory.select(mapSheetAnal.id).from(mapSheetAnal).where(builder).fetchCount(); queryFactory
.select(mapSheetAnalEntity.id)
.from(mapSheetAnalEntity)
.where(builder)
.fetchCount();
return new PageImpl<>(content, pageable, total); return new PageImpl<>(content, pageable, total);
} }
@@ -99,55 +100,40 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
// 1. 최신 버전 UID를 가져오는 서브쿼리 // 1. 최신 버전 UID를 가져오는 서브쿼리
JPQLQuery<Long> latestVerUidSub = JPQLQuery<Long> latestVerUidSub =
JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id)); JPAExpressions.select(tmv.id.max()).from(tmv).where(tmv.modelUid.eq(tmm.id));
Optional<InferenceResultDto.AnalResSummary> content = Optional<InferenceResultDto.AnalResSummary> content =
Optional.ofNullable( Optional.ofNullable(
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
InferenceResultDto.AnalResSummary.class, InferenceResultDto.AnalResSummary.class,
mapSheetAnal.id, mapSheetAnalEntity.id,
mapSheetAnal.analTitle, mapSheetAnalEntity.analTitle,
tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"), tmm.modelNm.concat(" ").concat(tmv.modelVer).as("modelInfo"),
mapSheetAnal.targetYyyy, mapSheetAnalEntity.targetYyyy,
mapSheetAnal.compareYyyy, mapSheetAnalEntity.compareYyyy,
mapSheetAnal.analMapSheet, mapSheetAnalEntity.analMapSheet,
mapSheetAnal.analStrtDttm, mapSheetAnalEntity.analStrtDttm,
mapSheetAnal.analEndDttm, mapSheetAnalEntity.analEndDttm,
mapSheetAnal.analSec, mapSheetAnalEntity.analSec,
mapSheetAnal.analPredSec, mapSheetAnalEntity.analPredSec,
mapSheetAnal.resultUrl, mapSheetAnalEntity.resultUrl,
mapSheetAnal.detectingCnt, mapSheetAnalEntity.detectingCnt,
mapSheetAnal.accuracy, mapSheetAnalEntity.accuracy,
mapSheetAnal.analState, mapSheetAnalEntity.analState,
Expressions.stringTemplate( Expressions.stringTemplate(
"fn_code_name({0}, {1})", "0002", mapSheetAnal.analState))) "fn_code_name({0}, {1})", "0002", mapSheetAnalEntity.analState)))
.from(mapSheetAnal) .from(mapSheetAnalEntity)
.leftJoin(tmm) .leftJoin(tmm)
.on(mapSheetAnal.modelUid.eq(tmm.id)) .on(mapSheetAnalEntity.modelUid.eq(tmm.id))
.leftJoin(tmv) .leftJoin(tmv)
.on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub))) .on(tmv.modelUid.eq(tmm.id).and(tmv.id.eq(latestVerUidSub)))
.where(mapSheetAnal.id.eq(id)) .where(mapSheetAnalEntity.id.eq(id))
.fetchOne()); .fetchOne());
return content; return content;
} }
/**
* 분석결과 상세 대시보드 조회
*
* @param id
* @return
*/
@Override
public List<MapSheetAnalSttcEntity> getInferenceResultDashboard(Long id) {
return queryFactory
.select(mapSheetAnalSttc)
.from(mapSheetAnalSttc)
.where(mapSheetAnalSttc.dataUid.eq(id))
.fetch();
}
/** /**
* 분석결과 상세 목록 * 분석결과 상세 목록
* *
@@ -155,52 +141,61 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
* @return * @return
*/ */
@Override @Override
public Page<InferenceResultDto.Geom> getInferenceGeomList(SearchGeoReq searchGeoReq) { public Page<InferenceResultDto.Geom> getInferenceGeomList(Long id, SearchGeoReq searchGeoReq) {
Pageable pageable = searchGeoReq.toPageable(); Pageable pageable = searchGeoReq.toPageable();
BooleanBuilder builder = new BooleanBuilder(); BooleanBuilder builder = new BooleanBuilder();
// 추론결과 id
builder.and(mapSheetAnalEntity.id.eq(id));
// 기준년도 분류 // 기준년도 분류
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) { if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().equals("")) {
builder.and(mapSheetAnalDataGeom.classAfterCd.eq(searchGeoReq.getTargetClass())); builder.and(mapSheetAnalDataGeomEntity.classAfterCd.eq(searchGeoReq.getTargetClass()));
} }
// 비교년도 분류 // 비교년도 분류
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) { if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().equals("")) {
builder.and(mapSheetAnalDataGeom.classBeforeCd.eq(searchGeoReq.getCompareClass())); builder.and(mapSheetAnalDataGeomEntity.classBeforeCd.eq(searchGeoReq.getCompareClass()));
} }
// 분석도엽 // 분석도엽
if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) { if (searchGeoReq.getMapSheetNum() != null && !searchGeoReq.getMapSheetNum().isEmpty()) {
List<Long> mapSheetNum = searchGeoReq.getMapSheetNum(); List<Long> mapSheetNum = searchGeoReq.getMapSheetNum();
builder.and(mapSheetAnalDataGeom.mapSheetNum.in(mapSheetNum)); builder.and(mapSheetAnalDataGeomEntity.mapSheetNum.in(mapSheetNum));
} }
List<InferenceResultDto.Geom> content = List<InferenceResultDto.Geom> content =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
InferenceResultDto.Geom.class, InferenceResultDto.Geom.class,
mapSheetAnalDataGeom.compareYyyy, mapSheetAnalDataGeomEntity.compareYyyy,
mapSheetAnalDataGeom.targetYyyy, mapSheetAnalDataGeomEntity.targetYyyy,
mapSheetAnalDataGeom.classBeforeCd, mapSheetAnalDataGeomEntity.classBeforeCd,
Expressions.stringTemplate( mapSheetAnalDataGeomEntity.classBeforeProb,
"fn_code_name({0}, {1})", "0000", mapSheetAnalDataGeom.classBeforeCd), mapSheetAnalDataGeomEntity.classAfterCd,
mapSheetAnalDataGeom.classBeforeProb, mapSheetAnalDataGeomEntity.classAfterProb,
mapSheetAnalDataGeom.classAfterCd, mapSheetAnalDataGeomEntity.mapSheetNum,
Expressions.stringTemplate( mapSheetAnalDataGeomEntity.geom,
"fn_code_name({0}, {1})", "0000", mapSheetAnalDataGeom.classAfterCd), mapSheetAnalDataGeomEntity.geomCenter))
mapSheetAnalDataGeom.classAfterProb, .from(mapSheetAnalEntity)
mapSheetAnalDataGeom.mapSheetNum)) .join(mapSheetAnalDataEntity)
.from(mapSheetAnalDataGeom) .on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
.where(builder) .join(mapSheetAnalDataGeomEntity)
.fetch(); .on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
.where(builder)
.fetch();
long total = long total =
queryFactory queryFactory
.select(mapSheetAnalDataGeom.id) .select(mapSheetAnalDataGeomEntity.id)
.from(mapSheetAnalDataGeom) .from(mapSheetAnalEntity)
.where(builder) .join(mapSheetAnalDataEntity)
.fetchCount(); .on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
.join(mapSheetAnalDataGeomEntity)
.on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
.where(builder)
.fetchCount();
return new PageImpl<>(content, pageable, total); return new PageImpl<>(content, pageable, total);
} }
@@ -214,12 +209,14 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC
@Override @Override
public List<Long> getSheets(Long id) { public List<Long> getSheets(Long id) {
return queryFactory return queryFactory
.select(mapSheetAnalDataGeom.mapSheetNum) .select(mapSheetAnalDataGeomEntity.mapSheetNum)
.from(mapSheetAnal) .from(mapSheetAnalEntity)
.join(mapSheetAnalEntity).on(mapSheetAnalEntity.analUid.eq(mapSheetAnal.id)) .join(mapSheetAnalDataEntity)
.join(mapSheetAnalDataGeom).on(mapSheetAnalDataGeom.dataUid.eq(mapSheetAnalEntity.id)) .on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
.where(mapSheetAnal.id.eq(id)) .join(mapSheetAnalDataGeomEntity)
.groupBy(mapSheetAnalDataGeom.mapSheetNum) .on(mapSheetAnalDataGeomEntity.dataUid.eq(mapSheetAnalDataEntity.id))
.fetch(); .where(mapSheetAnalEntity.id.eq(id))
.groupBy(mapSheetAnalDataGeomEntity.mapSheetNum)
.fetch();
} }
} }

View File

@@ -28,7 +28,8 @@ public interface MapSheetLearnDataGeomRepository
/** 데이터 UID로 유효하지 않은 지오메트리 데이터만 조건부 삭제 (안전성을 위해 직접 사용 금지) */ /** 데이터 UID로 유효하지 않은 지오메트리 데이터만 조건부 삭제 (안전성을 위해 직접 사용 금지) */
@Deprecated @Deprecated
@Query("DELETE FROM MapSheetLearnDataGeomEntity g WHERE g.dataUid = :dataUid AND (g.geom IS NULL OR g.geom.isEmpty() = true)") @Query(
"DELETE FROM MapSheetLearnDataGeomEntity g WHERE g.dataUid = :dataUid AND (g.geom IS NULL OR g.geom.isEmpty() = true)")
@Modifying @Modifying
@Transactional @Transactional
void deleteInvalidGeometryByDataUid(@Param("dataUid") Long dataUid); void deleteInvalidGeometryByDataUid(@Param("dataUid") Long dataUid);

View File

@@ -18,7 +18,7 @@ import java.util.List;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
implements ChangeDetectionRepositoryCustom { implements ChangeDetectionRepositoryCustom {
private final JPAQueryFactory queryFactory; private final JPAQueryFactory queryFactory;
@@ -36,75 +36,75 @@ public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
@Override @Override
public List<String> findPolygonJson() { public List<String> findPolygonJson() {
return queryFactory return queryFactory
.select(Expressions.stringTemplate("ST_AsGeoJSON({0})", mapSheetAnalDataGeomEntity.geom)) .select(Expressions.stringTemplate("ST_AsGeoJSON({0})", mapSheetAnalDataGeomEntity.geom))
.from(mapSheetAnalDataGeomEntity) .from(mapSheetAnalDataGeomEntity)
.orderBy(mapSheetAnalDataGeomEntity.id.desc()) .orderBy(mapSheetAnalDataGeomEntity.id.desc())
.fetch(); .fetch();
} }
@Override @Override
public List<ChangeDetectionDto.CountDto> getChangeDetectionClassCount(Long id) { public List<ChangeDetectionDto.CountDto> getChangeDetectionClassCount(Long id) {
return queryFactory return queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ChangeDetectionDto.CountDto.class, ChangeDetectionDto.CountDto.class,
mapSheetAnalSttcEntity.classAfterCd.toUpperCase(), mapSheetAnalSttcEntity.classAfterCd.toUpperCase(),
null, // TOOD classAfterName 삭제해서 수정 필요 null, // TOOD classAfterName 삭제해서 수정 필요
mapSheetAnalSttcEntity.classAfterCnt.sum())) mapSheetAnalSttcEntity.classAfterCnt.sum()))
.from(mapSheetAnalEntity) .from(mapSheetAnalEntity)
.innerJoin(mapSheetAnalDataEntity) .innerJoin(mapSheetAnalDataEntity)
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id)) .on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
.innerJoin(mapSheetAnalSttcEntity) .innerJoin(mapSheetAnalSttcEntity)
.on(mapSheetAnalSttcEntity.dataUid.eq(mapSheetAnalDataEntity.id)) .on(mapSheetAnalSttcEntity.dataUid.eq(mapSheetAnalDataEntity.id))
.where(mapSheetAnalEntity.id.eq(id)) .where(mapSheetAnalEntity.id.eq(id))
.groupBy(mapSheetAnalSttcEntity.classAfterCd) .groupBy(mapSheetAnalSttcEntity.classAfterCd)
.fetch(); .fetch();
} }
@Override @Override
public ChangeDetectionDto.CogUrlDto getChangeDetectionCogUrl(ChangeDetectionDto.CogUrlReq req) { public ChangeDetectionDto.CogUrlDto getChangeDetectionCogUrl(ChangeDetectionDto.CogUrlReq req) {
return queryFactory return queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ChangeDetectionDto.CogUrlDto.class, ChangeDetectionDto.CogUrlDto.class,
makeCogUrl(req.getBeforeYear()).max().as("beforeCogUrl"), makeCogUrl(req.getBeforeYear()).max().as("beforeCogUrl"),
makeCogUrl(req.getAfterYear()).max().as("afterCogUrl"), makeCogUrl(req.getAfterYear()).max().as("afterCogUrl"),
mapInkx5kEntity.geom.as("bbox"))) mapInkx5kEntity.geom.as("bbox")))
.from(imageryEntity) .from(imageryEntity)
.innerJoin(mapInkx5kEntity) .innerJoin(mapInkx5kEntity)
.on(imageryEntity.scene5k.eq(mapInkx5kEntity.mapidcdNo)) .on(imageryEntity.scene5k.eq(mapInkx5kEntity.mapidcdNo))
.where( .where(
imageryEntity imageryEntity
.year .year
.eq(req.getBeforeYear()) .eq(req.getBeforeYear())
.or(imageryEntity.year.eq(req.getAfterYear())), .or(imageryEntity.year.eq(req.getAfterYear())),
imageryEntity.scene5k.eq(req.getMapSheetNum())) imageryEntity.scene5k.eq(req.getMapSheetNum()))
.groupBy(mapInkx5kEntity.geom) .groupBy(mapInkx5kEntity.geom)
.fetchOne(); .fetchOne();
} }
@Override @Override
public List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList() { public List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList() {
return queryFactory return queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
ChangeDetectionDto.AnalYearList.class, ChangeDetectionDto.AnalYearList.class,
mapSheetAnalEntity.id, mapSheetAnalEntity.id,
mapSheetAnalEntity.analTitle, mapSheetAnalEntity.analTitle,
mapSheetAnalEntity.compareYyyy.as("beforeYear"), mapSheetAnalEntity.compareYyyy.as("beforeYear"),
mapSheetAnalEntity.targetYyyy.as("afterYear"), mapSheetAnalEntity.targetYyyy.as("afterYear"),
mapSheetAnalEntity.baseMapSheetNum)) mapSheetAnalEntity.baseMapSheetNum))
.from(mapSheetAnalEntity) .from(mapSheetAnalEntity)
.orderBy(mapSheetAnalEntity.id.asc()) .orderBy(mapSheetAnalEntity.id.asc())
.fetch(); .fetch();
} }
private StringExpression makeCogUrl(Integer year) { private StringExpression makeCogUrl(Integer year) {
return new CaseBuilder() return new CaseBuilder()
.when(imageryEntity.year.eq(year)) .when(imageryEntity.year.eq(year))
.then( .then(
Expressions.stringTemplate( Expressions.stringTemplate(
"{0} || {1}", imageryEntity.cogMiddlePath, imageryEntity.cogFilename)) "{0} || {1}", imageryEntity.cogMiddlePath, imageryEntity.cogFilename))
.otherwise(""); .otherwise("");
} }
} }