추론관리 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")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/code")
@RequestMapping({"/demo/code", "/api/code"})
public class CommonCodeApiController {
private final CommonCodeService commonCodeService;

View File

@@ -1,13 +1,48 @@
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "공통", description = "공통")
@RestController
@RequestMapping("/api/common")
@RequiredArgsConstructor
@RequestMapping({"/demo/common", "/api/common"})
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}")
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,7 +62,8 @@ public class GeometryConversionService {
try {
// 기존 geometry 데이터 확인 - 데이터가 이미 존재하고 유효한 경우 재처리 건너뛰기
List<MapSheetLearnDataGeomEntity> existingGeoms = mapSheetLearnDataGeomRepository.findByDataUid(learnData.getId());
List<MapSheetLearnDataGeomEntity> existingGeoms =
mapSheetLearnDataGeomRepository.findByDataUid(learnData.getId());
if (!existingGeoms.isEmpty() && isValidGeometryData(existingGeoms)) {
log.debug("유효한 geometry 데이터가 이미 존재합니다. 재처리를 건너뜁니다: {}", learnData.getId());
return existingGeoms.stream().map(MapSheetLearnDataGeomEntity::getId).toList();
@@ -70,9 +71,10 @@ public class GeometryConversionService {
// 유효하지 않은 데이터만 조건부 삭제 (null geometry 또는 잘못된 형식)
if (!existingGeoms.isEmpty()) {
List<MapSheetLearnDataGeomEntity> invalidGeoms = existingGeoms.stream()
.filter(g -> g.getGeom() == null || g.getGeom().isEmpty())
.toList();
List<MapSheetLearnDataGeomEntity> invalidGeoms =
existingGeoms.stream()
.filter(g -> g.getGeom() == null || g.getGeom().isEmpty())
.toList();
if (!invalidGeoms.isEmpty()) {
mapSheetLearnDataGeomRepository.deleteAll(invalidGeoms);
log.debug("유효하지 않은 geometry 데이터만 삭제했습니다: {}개", invalidGeoms.size());

View File

@@ -21,6 +21,7 @@ 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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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;
@Tag(name = "추론관리 분석결과", description = "추론관리 분석결과")
@RequestMapping("/api/inf/res")
@RequestMapping({"/demo/inf/res", "/api/inf/res"})
@RequiredArgsConstructor
@RestController
public class InferenceResultApiController {
@@ -53,10 +54,9 @@ public class InferenceResultApiController {
})
@GetMapping("/list")
public ApiResponseDto<Page<InferenceResultDto.AnalResList>> getInferenceResultList(
@Parameter(description = "분석상태", example = "0000") @RequestParam(required = false)
@Parameter(description = "분석상태", example = "0002") @RequestParam(required = false)
String statCode,
@Parameter(description = "제목", example = "2023_2024년도") @RequestParam(required = false)
String title,
@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")
@@ -84,9 +84,9 @@ public class InferenceResultApiController {
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/summary")
@GetMapping("/summary/{id}")
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));
}
@@ -122,11 +122,12 @@ public class InferenceResultApiController {
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/geom")
@GetMapping("/geom/{id}")
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,
@Parameter(description = "비교년도 분류", example = "0002") @RequestParam(required = false)
@Parameter(description = "비교년도 분류", example = "waste") @RequestParam(required = false)
String compareClass,
@Parameter(description = "5000:1 도협번호 37801011,37801012") @RequestParam(required = false)
List<Long> mapSheetNum,
@@ -141,7 +142,7 @@ public class InferenceResultApiController {
new InferenceResultDto.SearchGeoReq(
targetClass, compareClass, mapSheetNum, page, size, sort);
Page<InferenceResultDto.Geom> geomList =
inferenceResultService.getInferenceResultGeomList(searchGeoReq);
inferenceResultService.getInferenceResultGeomList(id, searchGeoReq);
return ApiResponseDto.ok(geomList);
}

View File

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

View File

@@ -1,7 +1,6 @@
package com.kamco.cd.kamcoback.inference.service;
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.postgres.core.InferenceResultCoreService;
import java.util.List;
@@ -38,16 +37,6 @@ public class InferenceResultService {
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
*/
public Page<InferenceResultDto.Geom> getInferenceResultGeomList(
InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultCoreService.getInferenceResultGeomList(searchGeoReq);
Long id, InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultCoreService.getInferenceResultGeomList(id, searchGeoReq);
}
/**
@@ -68,11 +57,16 @@ public class InferenceResultService {
public Detail getDetail(Long id) {
// summary
InferenceResultDto.AnalResSummary summary = this.getInferenceResultSummary(id);
// 탐지건수 dashBoard
List<InferenceResultDto.Dashboard> dashboardList = this.getInferenceResultBasic(id);
// 전체 탐지건수
Long totalCnt = dashboardList.stream().mapToLong(Dashboard::getClassAfterCnt).sum();
return new Detail(summary);
}
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;
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 jakarta.persistence.EntityNotFoundException;
import java.util.List;
@@ -22,7 +21,7 @@ public class InferenceResultCoreService {
* @return
*/
public Page<InferenceResultDto.AnalResList> getInferenceResultList(
InferenceResultDto.SearchReq searchReq) {
InferenceResultDto.SearchReq searchReq) {
return inferenceResultRepository.getInferenceResultList(searchReq);
}
@@ -34,25 +33,12 @@ public class InferenceResultCoreService {
*/
public InferenceResultDto.AnalResSummary getInferenceResultSummary(Long id) {
InferenceResultDto.AnalResSummary summary =
inferenceResultRepository
.getInferenceResultSummary(id)
.orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id));
inferenceResultRepository
.getInferenceResultSummary(id)
.orElseThrow(() -> new EntityNotFoundException("요약정보를 찾을 수 없습니다. " + id));
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
*/
public Page<InferenceResultDto.Geom> getInferenceResultGeomList(
InferenceResultDto.SearchGeoReq searchGeoReq) {
return inferenceResultRepository.getInferenceGeomList(searchGeoReq);
Long id, InferenceResultDto.SearchGeoReq 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 {
@Id
@GeneratedValue(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)
@GeneratedValue(
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)
private Long id;
@@ -119,6 +124,7 @@ public class MapSheetAnalDataGeomEntity {
@Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
private String fitStateCmmnt;
@Column(name = "ref_map_sheet_num")
private Long refMapSheetNum;
@@ -127,6 +133,4 @@ public class MapSheetAnalDataGeomEntity {
@Column(name = "geom_center", columnDefinition = "geometry")
private Geometry geomCenter;
}

View File

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

View File

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

View File

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

View File

@@ -28,7 +28,8 @@ public interface MapSheetLearnDataGeomRepository
/** 데이터 UID로 유효하지 않은 지오메트리 데이터만 조건부 삭제 (안전성을 위해 직접 사용 금지) */
@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
@Transactional
void deleteInvalidGeometryByDataUid(@Param("dataUid") Long dataUid);

View File

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