Merge pull request 'feat/infer_dev_260107' (#6) from feat/infer_dev_260107 into develop

Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
2026-01-29 16:25:08 +09:00
7 changed files with 81 additions and 35 deletions

View File

@@ -1,5 +1,7 @@
package com.kamco.cd.kamcoback.inference;
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.Scene;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto;
import com.kamco.cd.kamcoback.inference.service.InferenceResultShpService;
@@ -10,20 +12,28 @@ 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 java.util.Map;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
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;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "추론결과 데이터 생성", description = "추론결과 데이터 생성 API")
@Log4j2
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/inference/shp")
public class InferenceResultShpApiController {
private final InferenceResultShpService inferenceResultShpService;
public static final String MAP_ID =
"{ \"mapIds\": [\"37716096\",\"37716095\",\"37716094\",\"37716091\",\"37716086\",\"37716085\",\"37716084\",\"37716083\",\"37716076\",\"37716066\",\"37716065\",\"37716064\",\"37716063\",\"37716061\",\"37716051\",\"37716011\"] }";
@Operation(summary = "추론결과 데이터 저장", description = "추론결과 데이터 저장")
@ApiResponses(
@@ -52,4 +62,29 @@ public class InferenceResultShpApiController {
inferenceResultShpService.createShp(uuid);
return ApiResponseDto.createOK(null);
}
@Operation(summary = "추론실행에 필요한 geojson 파일 생성", description = "추론실행에 필요한 geojson 파일 생성")
@PostMapping("/geojson/{yyyy}/{mapSheetScope}/{detectOption}")
public ApiResponseDto<Scene> createGeojson(
@Schema(description = "년도") @PathVariable String yyyy,
@Schema(description = "전체(ALL),부분(PART)", example = "PART") @PathVariable
String mapSheetScope,
@Schema(description = "추론제외(EXCL),이전 년도 도엽 사용(PREV)", example = "EXCL") @PathVariable
String detectOption,
@Schema(description = "5k도엽번호", example = MAP_ID) @RequestBody Map<String, Object> body) {
Object raw = body.get("mapIds");
if (raw == null) {
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
}
@SuppressWarnings("unchecked")
List<String> mapIds = (List<String>) raw;
Scene scene =
inferenceResultShpService.createGeojson(yyyy, mapSheetScope, detectOption, mapIds);
return ApiResponseDto.createOK(scene);
}
}

View File

@@ -1,15 +1,20 @@
package com.kamco.cd.kamcoback.inference.service;
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.Scene;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceLearnDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService;
import com.kamco.cd.kamcoback.postgres.core.InferenceResultShpCoreService;
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
import com.kamco.cd.kamcoback.scheduler.service.ShpPipelineService;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -19,9 +24,11 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional(readOnly = true)
public class InferenceResultShpService {
private static final Logger log = LogManager.getLogger(InferenceResultShpService.class);
private final InferenceResultShpCoreService coreService;
private final InferenceResultCoreService inferenceResultCoreService;
private final ShpPipelineService shpPipelineService;
private final MapSheetMngCoreService mapSheetMngCoreService;
@Value("${mapsheet.shp.baseurl}")
private String baseDir;
@@ -59,4 +66,21 @@ public class InferenceResultShpService {
// shp 파일 비동기 생성
shpPipelineService.runPipeline(jarPath, datasetDir, batchId, dto.getUid());
}
/**
* 추론 실행전 geojson 파일 생성
*
* @param yyyy
* @param mapSheetScope
* @param detectOption
* @param mapIds
* @return
*/
public Scene createGeojson(
String yyyy, String mapSheetScope, String detectOption, List<String> mapIds) {
Scene getSceneInference =
mapSheetMngCoreService.getSceneInference(yyyy, mapIds, mapSheetScope, detectOption);
log.info("getSceneInference: {}", getSceneInference);
return getSceneInference;
}
}

View File

@@ -6,6 +6,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kE
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.QMapSheetLearnDataGeomEntity.mapSheetLearnDataGeomEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QPnuEntity.pnuEntity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -466,6 +467,14 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport
}
// 5. DTO 생성
// pnu list 조회
List<String> pnuList =
queryFactory
.select(pnuEntity.pnu)
.from(pnuEntity)
.where(pnuEntity.geo.geoUid.eq(mapSheetAnalDataInferenceGeomEntityEntity.getGeoUid()))
.fetch();
var changeDetectionInfo =
ChangeDetectionInfo.builder()
.mapSheetInfo(mapSheetEntity != null ? mapSheetEntity.getMapidNm() : "")
@@ -507,10 +516,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport
mapSheetAnalDataInferenceGeomEntityEntity.getCdProb() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getCdProb()
: 0.0)
.pnu(
mapSheetAnalDataInferenceGeomEntityEntity.getPnu() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getPnu()
: 0L)
.pnu(pnuList)
.mapSheetNum(
mapSheetAnalDataInferenceGeomEntityEntity.getMapSheetNum() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getMapSheetNum()

View File

@@ -7,6 +7,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceG
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity.mapSheetAnalInferenceEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnDataGeomEntity.mapSheetLearnDataGeomEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QPnuEntity.pnuEntity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -494,6 +495,14 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport
}
// 5. DTO 생성
// pnu list 조회
List<String> pnuList =
queryFactory
.select(pnuEntity.pnu)
.from(pnuEntity)
.where(pnuEntity.geo.geoUid.eq(mapSheetAnalDataInferenceGeomEntityEntity.getGeoUid()))
.fetch();
var changeDetectionInfo =
ChangeDetectionInfo.builder()
.mapSheetInfo(mapSheetEntity != null ? mapSheetEntity.getMapidNm() : "")
@@ -535,10 +544,7 @@ public class TrainingDataReviewRepositoryImpl extends QuerydslRepositorySupport
mapSheetAnalDataInferenceGeomEntityEntity.getCdProb() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getCdProb()
: 0.0)
.pnu(
mapSheetAnalDataInferenceGeomEntityEntity.getPnu() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getPnu()
: 0L)
.pnu(pnuList)
.mapSheetNum(
mapSheetAnalDataInferenceGeomEntityEntity.getMapSheetNum() != null
? mapSheetAnalDataInferenceGeomEntityEntity.getMapSheetNum()

View File

@@ -125,31 +125,6 @@ public class TrainingDataReviewJobService {
return result;
}
// 라벨러 완료,SKIP 시 호출 -> 미사용
@Transactional
public void assignRealtime(String assignmentUid) {
Tasks task = trainingDataReviewJobCoreService.findAssignmentTask(assignmentUid);
Long analUid = task.getAnalUid();
// pending 계산
List<InspectorPendingDto> pendings =
trainingDataReviewJobCoreService.findInspectorPendingByRound(analUid);
if (pendings.isEmpty()) {
return;
}
List<String> order = pendings.stream().map(InspectorPendingDto::getInspectorUid).toList();
trainingDataReviewJobCoreService.lockInspectors(analUid, order);
trainingDataReviewJobCoreService.assignReviewer(task.getAssignmentUid(), order.getFirst());
List<Long> geomUids = new ArrayList<>();
geomUids.add(task.getInferenceUid());
trainingDataReviewJobCoreService.updateGeomUidTestState(geomUids);
}
@Transactional
@Scheduled(cron = "0 0 2 * * *")
public void exportGeojsonLabelingGeom() {

View File

@@ -358,7 +358,7 @@ public class TrainingDataLabelDto {
private Double detectionAccuracy;
@Schema(description = "PNU (필지고유번호)", example = "36221202306020")
private Long pnu;
private List<String> pnu;
@Schema(description = "도엽번호 (map_sheet_num)", example = "34602057")
private Long mapSheetNum;

View File

@@ -351,7 +351,7 @@ public class TrainingDataReviewDto {
private Double detectionAccuracy;
@Schema(description = "PNU (필지고유번호)", example = "36221202306020")
private Long pnu;
private List<String> pnu;
@Schema(description = "도엽번호 (map_sheet_num)", example = "34602057")
private Long mapSheetNum;