From 3271315d38540d1cf4b1982209f6b6b3c28dcbdb Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 20 Jan 2026 16:57:40 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AF=B8=EC=82=AC=EC=9A=A9=20=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InferenceResultShpApiController.java | 19 - .../inference/service/GeoToolsShpWriter.java | 364 ------------------ .../service/InferenceResultShpService.java | 70 ---- .../inference/service/ShpWriter.java | 14 - .../core/InferenceResultShpCoreService.java | 44 --- .../InferenceResultRepositoryCustom.java | 14 - .../InferenceResultRepositoryImpl.java | 144 ------- 7 files changed, 669 deletions(-) delete mode 100644 src/main/java/com/kamco/cd/kamcoback/inference/service/GeoToolsShpWriter.java delete mode 100644 src/main/java/com/kamco/cd/kamcoback/inference/service/ShpWriter.java diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultShpApiController.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultShpApiController.java index 9cdf503e..a431bcb1 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultShpApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultShpApiController.java @@ -42,23 +42,4 @@ public class InferenceResultShpApiController { @PathVariable Long learnId) { return ApiResponseDto.createOK(inferenceResultShpService.saveInferenceResultData(learnId)); } - - @Operation(summary = "shp 파일 생성", description = "shp 파일 생성") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "201", - description = "파일생성 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = InferenceResultShpDto.FileCntDto.class))), - @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @PostMapping("/create/{learnId}") - public ApiResponseDto createShpFile( - @PathVariable Long learnId) { - return ApiResponseDto.createOK(inferenceResultShpService.createShpFile(learnId)); - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/GeoToolsShpWriter.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/GeoToolsShpWriter.java deleted file mode 100644 index 5d43f91d..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/GeoToolsShpWriter.java +++ /dev/null @@ -1,364 +0,0 @@ -package com.kamco.cd.kamcoback.inference.service; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto; -import com.kamco.cd.kamcoback.inference.dto.WriteCnt; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.io.Serializable; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.geotools.api.data.SimpleFeatureSource; -import org.geotools.api.data.SimpleFeatureStore; -import org.geotools.api.data.Transaction; -import org.geotools.api.feature.simple.SimpleFeature; -import org.geotools.api.feature.simple.SimpleFeatureType; -import org.geotools.api.referencing.crs.CoordinateReferenceSystem; -import org.geotools.data.shapefile.ShapefileDataStore; -import org.geotools.data.shapefile.ShapefileDataStoreFactory; -import org.geotools.feature.DefaultFeatureCollection; -import org.geotools.feature.simple.SimpleFeatureBuilder; -import org.geotools.feature.simple.SimpleFeatureTypeBuilder; -import org.geotools.geojson.geom.GeometryJSON; -import org.geotools.referencing.CRS; -import org.locationtech.jts.geom.Geometry; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class GeoToolsShpWriter implements ShpWriter { - - // DBF 파일 한글 깨짐 방지를 위해 EUC-KR 사용 - private static final Charset DBF_CHARSET = Charset.forName("EUC-KR"); - - // GeoJSON 출력은 UTF-8 - private static final Charset GEOJSON_CHARSET = StandardCharsets.UTF_8; - - // 좌표계: Korea 2000 / Central Belt 2010 - private static final String EPSG_5186 = "EPSG:5186"; - - /** - * SHP 파일(.shp/.shx/.dbf/.prj)을 생성한다. - * - *

- shpBasePath를 기준으로 파일을 생성한다. 예) /Users/kim/export/shp/1_map_2021_2022 → 1_map_2021_2022.shp - * → 1_map_2021_2022.shx → 1_map_2021_2022.dbf → 1_map_2021_2022.prj - * - *

- geometry 타입은 첫 번째 유효 geometry 기준으로 스키마를 생성한다. - 좌표계는 EPSG:5186으로 설정하며, .prj 파일을 직접 생성한다. - * - * @param shpBasePath 확장자를 제외한 SHP 파일 기본 경로 - * @param rows 동일 그룹(stage, mapId, input1, input2)의 데이터 목록 - * @return 이번 호출로 write(생성/덮어쓰기)가 수행된 파일 개수 - */ - @Override - public WriteCnt writeShp(String shpBasePath, List rows) { - - if (rows == null || rows.isEmpty()) { - return WriteCnt.zero(); - } - - // SHP는 Geometry.class를 허용하지 않으므로 - // 첫 번째 유효 geometry의 "구체 타입"을 기준으로 스키마를 생성한다. - Geometry firstGeom = firstNonNullGeometry(rows); - if (firstGeom == null) { - throw new IllegalArgumentException("SHP 생성 실패: geometry가 전부 null 입니다. path=" + shpBasePath); - } - - @SuppressWarnings("unchecked") - Class geomType = (Class) firstGeom.getClass(); - - ShapefileDataStore dataStore = null; - - try { - File shpFile = new File(shpBasePath + ".shp"); - createDirectories(shpFile); - - // EPSG:5186 CRS 로딩 - CoordinateReferenceSystem crs = CRS.decode(EPSG_5186, false); - - // FeatureType(schema) 생성 - SimpleFeatureType schema = createSchema(geomType, crs); - - // ShapefileDataStore 생성 (기존 파일이 있어도 새로 생성/overwrite 동작) - dataStore = createDataStore(shpFile, schema); - - // FeatureCollection 생성 - DefaultFeatureCollection collection = buildFeatureCollection(schema, rows); - - // 실제 SHP 파일에 feature 쓰기 - writeFeatures(dataStore, collection); - - // .prj 파일 직접 생성 (EPSG:5186) - writePrjFile(shpBasePath, crs); - - log.info("SHP 생성 완료: {} ({} features)", shpFile.getAbsolutePath(), collection.size()); - - // 덮어쓰기 포함: 이번 호출이 정상 종료되면 4개 파일 write가 발생했다고 카운트 - return new WriteCnt(1, 1, 1, 1, 0); - - } catch (Exception e) { - throw new RuntimeException("SHP 생성 실패: " + shpBasePath, e); - } finally { - if (dataStore != null) { - try { - dataStore.dispose(); - } catch (Exception ignore) { - } - } - } - } - - /** - * GeoJSON 파일(.geojson)을 생성한다. - * - *

- FeatureCollection 형태로 출력한다. - 최상단에 name / crs / properties를 포함한다. - 각 Feature는 polygon 단위로 - * 생성된다. - geometry는 GeoTools GeometryJSON을 사용하여 직렬화한다. - * - *

GeoJSON 구조 예: { "type": "FeatureCollection", "name": "stage_input1_input2_mapId", "crs": { - * "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::5186" } }, "properties": { ... - * }, "features": [ ... ] } - * - * @param geoJsonPath 생성할 GeoJSON 파일의 전체 경로 (.geojson 포함) - * @param rows 동일 그룹(stage, mapId, input1, input2)의 데이터 목록 - * @return 이번 호출로 write(생성/덮어쓰기)가 수행된 파일 개수 - */ - @Override - public WriteCnt writeGeoJson(String geoJsonPath, List rows) { - - if (rows == null || rows.isEmpty()) { - return WriteCnt.zero(); - } - - try { - File geoJsonFile = new File(geoJsonPath); - createDirectories(geoJsonFile); - - // 그룹 공통 메타 정보는 첫 row 기준 - InferenceResultShpDto.Basic first = rows.get(0); - - ObjectMapper om = new ObjectMapper(); - GeometryJSON gj = new GeometryJSON(15); - - // FeatureCollection 루트 - ObjectNode root = om.createObjectNode(); - root.put("type", "FeatureCollection"); - - // name: stage_input1_input2_mapId - String name = - String.format( - "%d_%d_%d_%d", - first.getStage(), first.getInput1(), first.getInput2(), first.getMapId()); - root.put("name", name); - - // CRS (EPSG:5186) - ObjectNode crs = om.createObjectNode(); - crs.put("type", "name"); - ObjectNode crsProps = om.createObjectNode(); - crsProps.put("name", "urn:ogc:def:crs:EPSG::5186"); - crs.set("properties", crsProps); - root.set("crs", crs); - - // 그룹 공통 properties - ObjectNode groupProps = om.createObjectNode(); - groupProps.put("stage", first.getStage()); - groupProps.put("input1", first.getInput1()); - groupProps.put("input2", first.getInput2()); - groupProps.put("map_id", first.getMapId()); - root.set("properties", groupProps); - - // features 배열 - ArrayNode features = om.createArrayNode(); - - for (InferenceResultShpDto.Basic dto : rows) { - if (dto.getGeometry() == null) { - continue; - } - - ObjectNode feature = om.createObjectNode(); - feature.put("type", "Feature"); - - // feature properties - ObjectNode p = om.createObjectNode(); - p.put("polygon_id", dto.getUuid() != null ? dto.getUuid().toString() : null); - if (dto.getCdProb() != null) { - p.put("cd_prob", dto.getCdProb()); - } - if (dto.getInput1() != null) { - p.put("input1", dto.getInput1()); - } - if (dto.getInput2() != null) { - p.put("input2", dto.getInput2()); - } - if (dto.getMapId() != null) { - p.put("map_id", dto.getMapId()); - } - if (dto.getArea() != null) { - p.put("area", dto.getArea()); - } - p.put("before_c", dto.getBeforeClass()); - if (dto.getBeforeProbability() != null) { - p.put("before_p", dto.getBeforeProbability()); - } - p.put("after_c", dto.getAfterClass()); - if (dto.getAfterProbability() != null) { - p.put("after_p", dto.getAfterProbability()); - } - - feature.set("properties", p); - - // geometry - String geomJson = gj.toString(dto.getGeometry()); - JsonNode geomNode = om.readTree(geomJson); - feature.set("geometry", geomNode); - - features.add(feature); - } - - root.set("features", features); - - // 파일 쓰기 - try (OutputStreamWriter w = - new OutputStreamWriter(new FileOutputStream(geoJsonFile), GEOJSON_CHARSET)) { - om.writerWithDefaultPrettyPrinter().writeValue(w, root); - } - - log.info("GeoJSON 생성 완료: {} ({} features)", geoJsonFile.getAbsolutePath(), features.size()); - - // 덮어쓰기 포함: 이번 호출이 정상 종료되면 geojson 1개 write로 카운트 - return new WriteCnt(0, 0, 0, 0, 1); - - } catch (Exception e) { - throw new RuntimeException("GeoJSON 생성 실패: " + geoJsonPath, e); - } - } - - private Geometry firstNonNullGeometry(List rows) { - for (InferenceResultShpDto.Basic r : rows) { - if (r != null && r.getGeometry() != null) { - return r.getGeometry(); - } - } - return null; - } - - private SimpleFeatureType createSchema( - Class geomType, CoordinateReferenceSystem crs) { - SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder(); - b.setName("inference_result"); - b.setCRS(crs); - - // geometry는 반드시 첫 컬럼 - b.add("the_geom", geomType); - - // DBF 컬럼 정의 (10자 제한 고려) - b.length(36).add("poly_id", String.class); - b.add("cd_prob", Double.class); - b.add("input1", Integer.class); - b.add("input2", Integer.class); - b.add("map_id", Long.class); - b.add("area", Double.class); - b.length(20).add("before_c", String.class); - b.add("before_p", Double.class); - b.length(20).add("after_c", String.class); - b.add("after_p", Double.class); - - return b.buildFeatureType(); - } - - /** - * .shp .shx .dbf .fix 파일 생성 (껍데기 생성) - * - * @param shpFile - * @param schema - * @return - * @throws Exception - */ - private ShapefileDataStore createDataStore(File shpFile, SimpleFeatureType schema) - throws Exception { - - Map params = new HashMap<>(); - params.put("url", shpFile.toURI().toURL()); - - // .fix 파일 생성 Boolean.TRUE, 미생성 Boolean.FALSE - params.put("create spatial index", Boolean.FALSE); - - ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory(); - - ShapefileDataStore dataStore = (ShapefileDataStore) factory.createNewDataStore(params); - - dataStore.setCharset(DBF_CHARSET); - dataStore.createSchema(schema); - - return dataStore; - } - - private DefaultFeatureCollection buildFeatureCollection( - SimpleFeatureType schema, List rows) { - DefaultFeatureCollection collection = new DefaultFeatureCollection(); - SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); - - for (InferenceResultShpDto.Basic dto : rows) { - if (dto == null || dto.getGeometry() == null) { - continue; - } - - builder.add(dto.getGeometry()); - builder.add(dto.getUuid() != null ? dto.getUuid().toString() : null); - builder.add(dto.getCdProb() != null ? dto.getCdProb().doubleValue() : null); - builder.add(dto.getInput1()); - builder.add(dto.getInput2()); - builder.add(dto.getMapId()); - builder.add(dto.getArea() != null ? dto.getArea().doubleValue() : null); - builder.add(dto.getBeforeClass()); - builder.add( - dto.getBeforeProbability() != null ? dto.getBeforeProbability().doubleValue() : null); - builder.add(dto.getAfterClass()); - builder.add( - dto.getAfterProbability() != null ? dto.getAfterProbability().doubleValue() : null); - - SimpleFeature feature = builder.buildFeature(null); - collection.add(feature); - builder.reset(); - } - - return collection; - } - - private void writeFeatures(ShapefileDataStore dataStore, DefaultFeatureCollection collection) - throws Exception { - - String typeName = dataStore.getTypeNames()[0]; - SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName); - - if (!(featureSource instanceof SimpleFeatureStore store)) { - throw new IllegalStateException("FeatureStore 생성 실패"); - } - - store.setTransaction(Transaction.AUTO_COMMIT); - store.addFeatures(collection); - store.getTransaction().commit(); - } - - private void writePrjFile(String shpBasePath, CoordinateReferenceSystem crs) throws Exception { - - File prjFile = new File(shpBasePath + ".prj"); - createDirectories(prjFile); - - Files.writeString(prjFile.toPath(), crs.toWKT(), StandardCharsets.UTF_8); - } - - private void createDirectories(File file) throws Exception { - File parent = file.getParentFile(); - if (parent != null) { - Files.createDirectories(parent.toPath()); - } - } -} diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java index 64f7b7ab..6dd1fe36 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultShpService.java @@ -1,9 +1,7 @@ package com.kamco.cd.kamcoback.inference.service; import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto; -import com.kamco.cd.kamcoback.inference.dto.WriteCnt; import com.kamco.cd.kamcoback.postgres.core.InferenceResultShpCoreService; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -15,7 +13,6 @@ import org.springframework.transaction.annotation.Transactional; public class InferenceResultShpService { private final InferenceResultShpCoreService coreService; - private final ShpWriter shpWriter; @Value("${mapsheet.shp.baseurl}") private String baseDir; @@ -25,71 +22,4 @@ public class InferenceResultShpService { public InferenceResultShpDto.InferenceCntDto saveInferenceResultData(Long id) { return coreService.buildInferenceData(id); } - - /** - * 분석 데이터 단위로 SHP / GeoJSON 파일을 생성한다. - * - *

처리 흐름: 1. 파일 미생성 상태의 분석 데이터 조회 2. 재생성을 위한 상태 초기화 3. 도형 데이터 조회 4. SHP / GeoJSON 파일 생성 5. 파일 - * 생성 완료 상태 반영 - * - *

중간 실패 시 다음 실행에서 전체 재생성된다. - */ - @Transactional - public InferenceResultShpDto.FileCntDto createShpFile(Long learnId) { - - // TODO 배치 실행으로 변경 필요 - int batchSize = 100; - int geomLimit = 500_000; - - WriteCnt total = WriteCnt.zero(); - - List dataUids = coreService.findPendingDataUids(batchSize, learnId); - - for (Long dataUid : dataUids) { - - // 재생성을 위한 생성 상태 초기화 - coreService.resetForRegenerate(dataUid); - - // 추론 데이터 조회 - List dtoList = coreService.loadGeomDtos(dataUid, geomLimit); - if (dtoList.isEmpty()) { - continue; - } - - // 파일명 생성 (stage_mapSheet_compare_target) - InferenceResultShpDto.Basic first = dtoList.get(0); - String baseName = - String.format( - "%d_%d_%d_%d", - first.getStage(), first.getMapId(), first.getInput1(), first.getInput2()); - - String baseDir2 = "/" + first.getInput1() + "_" + first.getInput2() + "/" + first.getStage(); - String shpBasePath = baseDir + baseDir2 + "/shp/" + baseName; - String geoJsonPath = baseDir + baseDir2 + "/geojson/" + baseName + ".geojson"; - - try { - // Writer가 "이번 호출에서 write한 개수"를 반환 - total = total.plus(shpWriter.writeShp(shpBasePath, dtoList)); - total = total.plus(shpWriter.writeGeoJson(geoJsonPath, dtoList)); - - // 파일 생성 완료 상태 반영 - List geoUids = dtoList.stream().map(InferenceResultShpDto.Basic::getGeoUid).toList(); - coreService.markSuccess(dataUid, geoUids); - - } catch (Exception e) { - // 실패 시 markSuccess 하지 않음 -> 다음 실행에서 재생성 - // log.warn("파일 생성 실패: dataUid={}, baseName={}", dataUid, baseName, e); - continue; - } - } - - InferenceResultShpDto.FileCntDto fileCntDto = new InferenceResultShpDto.FileCntDto(); - fileCntDto.setShp(total.shp()); - fileCntDto.setShx(total.shx()); - fileCntDto.setDbf(total.dbf()); - fileCntDto.setPrj(total.prj()); - fileCntDto.setGeojson(total.geojson()); - - return fileCntDto; - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/ShpWriter.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/ShpWriter.java deleted file mode 100644 index 84a47249..00000000 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/ShpWriter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.kamco.cd.kamcoback.inference.service; - -import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto; -import com.kamco.cd.kamcoback.inference.dto.WriteCnt; -import java.util.List; - -public interface ShpWriter { - - // SHP (.shp/.shx/.dbf/.fix) - WriteCnt writeShp(String shpBasePath, List rows); - - // GeoJSON (.geojson) - WriteCnt writeGeoJson(String geoJsonPath, List rows); -} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultShpCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultShpCoreService.java index 17a25275..c2d8038b 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultShpCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultShpCoreService.java @@ -1,9 +1,7 @@ package com.kamco.cd.kamcoback.postgres.core; import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,46 +26,4 @@ public class InferenceResultShpCoreService { return cntDto; } - - /** 파일 생성이 완료되지 않은 분석 데이터(data_uid) 목록을 조회한다. */ - @Transactional(readOnly = true) - public List findPendingDataUids(int limit, Long learnId) { - return repo.findPendingDataUids(limit, learnId); - } - - /** - * 분석 데이터 재생성을 위해 기존 파일 생성 상태를 초기화한다. - * - *

- 분석 데이터(file_created_yn)를 미생성 상태로 변경 - 해당 분석 데이터에 속한 모든 도형의 생성 상태를 미생성으로 변경 - */ - @Transactional - public void resetForRegenerate(Long dataUid) { - repo.resetInferenceCreated(dataUid); - repo.resetGeomCreatedByDataUid(dataUid); - } - - /** - * 지정된 분석 데이터에 속한 도형 정보를 조회한다. - * - *

- 파일 미생성 상태의 도형만 대상 - geometry가 존재하는 도형만 조회 - */ - @Transactional(readOnly = true) - public List loadGeomDtos(Long dataUid, int limit) { - List entities = - repo.findGeomEntitiesByDataUid(dataUid, limit); - - return entities.stream().map(InferenceResultShpDto.Basic::from).toList(); - } - - /** - * 파일 생성이 성공한 도형 및 분석 데이터에 대해 생성 완료 상태로 갱신한다. - * - * @param dataUid 분석 데이터 UID - * @param geoUids 파일 생성이 완료된 도형 UID 목록 - */ - @Transactional - public void markSuccess(Long dataUid, List geoUids) { - repo.markGeomCreatedByGeoUids(geoUids); - repo.markInferenceCreated(dataUid); - } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryCustom.java index c3162853..da1c2b6a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryCustom.java @@ -1,8 +1,6 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; -import java.util.List; import java.util.Optional; import java.util.UUID; @@ -16,18 +14,6 @@ public interface InferenceResultRepositoryCustom { void upsertSttcFromInferenceResults(Long analId); - List findPendingDataUids(int limit, Long learnId); - - int resetInferenceCreated(Long dataUid); - - int markInferenceCreated(Long dataUid); - - int resetGeomCreatedByDataUid(Long dataUid); - - int markGeomCreatedByGeoUids(List geoUids); - - List findGeomEntitiesByDataUid(Long dataUid, int limit); - Long getInferenceLearnIdByUuid(UUID uuid); public Optional getInferenceUid(UUID uuid); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryImpl.java index 0630476e..70ba071f 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/InferenceResultRepositoryImpl.java @@ -3,15 +3,12 @@ package com.kamco.cd.kamcoback.postgres.repository.Inference; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnEntity.mapSheetLearnEntity; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelMngState; -import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalInferenceEntity; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; -import java.time.ZonedDateTime; -import java.util.List; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -328,151 +325,10 @@ public class InferenceResultRepositoryImpl implements InferenceResultRepositoryC em.createNativeQuery(sql).setParameter("analUid", analUid).executeUpdate(); } - // =============================== - // Jobs - // =============================== - - /** - * 파일 생성이 완료되지 않은 분석 데이터(data_uid) 목록을 조회한다. - * - * @param limit 최대 조회 건수 - * @return data_uid 목록 - */ - @Override - public List findPendingDataUids(int limit, Long learnId) { - - return queryFactory - .select(inferenceDataEntity.id) - .from(inferenceEntity) - .innerJoin(inferenceDataEntity) - .on(inferenceEntity.id.eq(inferenceDataEntity.analUid)) - .where( - inferenceEntity - .learnId - .eq(learnId) - .and( - inferenceDataEntity - .fileCreatedYn - .isFalse() - .or(inferenceDataEntity.fileCreatedYn.isNull()))) - .orderBy(inferenceDataEntity.id.asc()) - .limit(limit) - .fetch(); - } - - // =============================== - // Reset / Mark - // =============================== - - /** - * 분석 데이터의 파일 생성 상태를 재생성 가능 상태로 초기화한다. - * - *

- file_created_yn = false - file_created_dttm = null - * - * @return 갱신된 행 수 - */ - @Override - public int resetInferenceCreated(Long dataUid) { - ZonedDateTime now = ZonedDateTime.now(); - - return (int) - queryFactory - .update(inferenceDataEntity) - .set(inferenceDataEntity.fileCreatedYn, false) - .set(inferenceDataEntity.fileCreatedDttm, (ZonedDateTime) null) - .set(inferenceDataEntity.updatedDttm, now) - .where(inferenceDataEntity.id.eq(dataUid)) - .execute(); - } - - /** - * 분석 데이터의 파일 생성 완료 상태를 반영한다. - * - * @return 갱신된 행 수 - */ - @Override - public int markInferenceCreated(Long dataUid) { - ZonedDateTime now = ZonedDateTime.now(); - - return (int) - queryFactory - .update(inferenceDataEntity) - .set(inferenceDataEntity.fileCreatedYn, true) - .set(inferenceDataEntity.fileCreatedDttm, now) - .set(inferenceDataEntity.updatedDttm, now) - .where(inferenceDataEntity.id.eq(dataUid)) - .execute(); - } - - /** - * 분석 데이터에 속한 모든 도형의 파일 생성 상태를 초기화한다. - * - * @return 갱신된 행 수 - */ - @Override - public int resetGeomCreatedByDataUid(Long dataUid) { - ZonedDateTime now = ZonedDateTime.now(); - - return (int) - queryFactory - .update(inferenceGeomEntity) - .set(inferenceGeomEntity.fileCreatedYn, false) - .set(inferenceGeomEntity.fileCreatedDttm, (ZonedDateTime) null) - .set(inferenceGeomEntity.updatedDttm, now) - .where(inferenceGeomEntity.dataUid.eq(dataUid)) - .execute(); - } - - /** - * 파일 생성이 완료된 도형(geo_uid)을 생성 완료 상태로 반영한다. - * - * @param geoUids 생성 완료된 도형 UID 목록 - * @return 갱신된 행 수 - */ - @Override - public int markGeomCreatedByGeoUids(List geoUids) { - if (geoUids == null || geoUids.isEmpty()) { - return 0; - } - - ZonedDateTime now = ZonedDateTime.now(); - - return (int) - queryFactory - .update(inferenceGeomEntity) - .set(inferenceGeomEntity.fileCreatedYn, true) - .set(inferenceGeomEntity.fileCreatedDttm, now) - .set(inferenceGeomEntity.updatedDttm, now) - .where(inferenceGeomEntity.geoUid.in(geoUids)) - .execute(); - } - // =============================== // Export source (Entity only) // =============================== - /** - * SHP / GeoJSON 파일 생성을 위한 도형 데이터 조회 - * - *

- 특정 분석 데이터(data_uid)에 속한 도형 - geometry 존재 - 파일 미생성 상태만 대상 - */ - @Override - public List findGeomEntitiesByDataUid( - Long dataUid, int limit) { - return queryFactory - .selectFrom(inferenceGeomEntity) - .where( - inferenceGeomEntity.dataUid.eq(dataUid), - inferenceGeomEntity.geom.isNotNull(), - inferenceGeomEntity - .fileCreatedYn - .isFalse() - .or(inferenceGeomEntity.fileCreatedYn.isNull())) - .orderBy(inferenceGeomEntity.geoUid.asc()) - .limit(limit) - .fetch(); - } - @Override public Long getInferenceLearnIdByUuid(UUID uuid) { return queryFactory