From cd1a79049ae6dfa02303180421e513d71fd94eec Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Mon, 12 Jan 2026 16:39:58 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EB=B2=A8=EB=A7=81=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=ED=85=8C=EC=9D=B4=EB=B8=94=20learn=20data=20?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/geometry/GeometryDeserializer.java | 4 +- .../entity/MapSheetLearnDataGeomEntity.java | 43 ++++++++ .../TrainingDataLabelRepositoryImpl.java | 103 +++++++++++++----- .../dto/TrainingDataLabelDto.java | 3 + 4 files changed, 126 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnDataGeomEntity.java diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java index ea9366a3..2e0c68e9 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java @@ -32,7 +32,9 @@ public class GeometryDeserializer extends StdDeserializer try { GeoJsonReader reader = new GeoJsonReader(); - return (T) reader.read(json); + Geometry geometry = reader.read(json); + geometry.setSRID(5186); + return (T) geometry; } catch (Exception e) { throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnDataGeomEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnDataGeomEntity.java new file mode 100644 index 00000000..e5815451 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapSheetLearnDataGeomEntity.java @@ -0,0 +1,43 @@ +package com.kamco.cd.kamcoback.postgres.entity; + +import com.kamco.cd.kamcoback.postgres.CommonDateEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.Setter; +import org.locationtech.jts.geom.Geometry; + +/** 라벨링 툴에서 그린 폴리곤 저장 테이블 */ +@Getter +@Setter +@Entity +@Table(name = "tb_map_sheet_learn_data_geom") +public class MapSheetLearnDataGeomEntity extends CommonDateEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "geo_uid", nullable = false) + private Long geoUid; + + @Column(name = "after_yyyy") + private Integer afterYyyy; + + @Column(name = "area") + private Double area; + + @Column(name = "before_yyyy") + private Integer beforeYyyy; + + @Column(name = "class_after_cd") + private String classAfterCd; + + @Column(name = "class_before_cd") + private String classBeforeCd; + + @Column(name = "geom") + private Geometry geom; +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java index abdc1799..0107e0cc 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/trainingdata/TrainingDataLabelRepositoryImpl.java @@ -4,11 +4,17 @@ import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntit import static com.kamco.cd.kamcoback.postgres.entity.QLabelingAssignmentEntity.labelingAssignmentEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity; import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataInferenceGeomEntity.mapSheetAnalDataInferenceGeomEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetLearnDataGeomEntity.mapSheetLearnDataGeomEntity; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.kamco.cd.kamcoback.postgres.entity.LabelingAssignmentEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; +import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.ChangeDetectionInfo; +import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.ClassificationInfo; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.DetailRes; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.GeoFeatureRequest.Properties; +import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InspectionResultInfo; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingGeometryInfo; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.LabelingListDto; import com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.SummaryRes; @@ -20,6 +26,7 @@ import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.NumberPath; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityNotFoundException; import java.time.LocalDate; import java.time.ZonedDateTime; import java.util.List; @@ -170,24 +177,48 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport @Override public void updateLabelingPolygonClass( - Long mapSheetAnalDataInferenceGeomEntityUid, - Geometry geometry, - Properties properties, - String status) { + Long inferenceGeomUid, Geometry geometry, Properties properties, String status) { + // inference_geom 테이블에 상태 업데이트 queryFactory .update(mapSheetAnalDataInferenceGeomEntity) - .set(mapSheetAnalDataInferenceGeomEntity.geom, geometry) - .set( - mapSheetAnalDataInferenceGeomEntity.classBeforeCd, - properties.getBeforeClass().toLowerCase()) - .set( - mapSheetAnalDataInferenceGeomEntity.classAfterCd, - properties.getAfterClass().toLowerCase()) .set(mapSheetAnalDataInferenceGeomEntity.labelStateDttm, ZonedDateTime.now()) .set(mapSheetAnalDataInferenceGeomEntity.labelState, status) - .set(mapSheetAnalDataInferenceGeomEntity.geomCenter, geometry.getCentroid()) - .where( - mapSheetAnalDataInferenceGeomEntity.geoUid.eq(mapSheetAnalDataInferenceGeomEntityUid)) + .where(mapSheetAnalDataInferenceGeomEntity.geoUid.eq(inferenceGeomUid)) + .execute(); + + // compareYyyy, targetYyyy 정보 가져오기 + MapSheetAnalDataInferenceGeomEntity entity = + queryFactory + .selectFrom(mapSheetAnalDataInferenceGeomEntity) + .where(mapSheetAnalDataInferenceGeomEntity.geoUid.eq(inferenceGeomUid)) + .fetchOne(); + + if (Objects.isNull(entity)) { + throw new EntityNotFoundException( + "MapSheetAnalDataInferenceGeomEntity not found for analUid: "); + } + + // learn_data_geom 에 insert + queryFactory + .insert(mapSheetLearnDataGeomEntity) + .columns( + mapSheetLearnDataGeomEntity.geoUid, + mapSheetLearnDataGeomEntity.afterYyyy, + mapSheetLearnDataGeomEntity.beforeYyyy, + mapSheetLearnDataGeomEntity.classAfterCd, + mapSheetLearnDataGeomEntity.classBeforeCd, + mapSheetLearnDataGeomEntity.geom, + mapSheetLearnDataGeomEntity.createdDate, + mapSheetLearnDataGeomEntity.modifiedDate) + .values( + inferenceGeomUid, + entity.getTargetYyyy(), + entity.getCompareYyyy(), + properties.getAfterClass().toLowerCase(), + properties.getBeforeClass().toLowerCase(), + geometry, + ZonedDateTime.now(), + ZonedDateTime.now()) .execute(); } @@ -370,7 +401,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport // 5. DTO 생성 var changeDetectionInfo = - com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.ChangeDetectionInfo.builder() + ChangeDetectionInfo.builder() .mapSheetInfo(mapSheetEntity != null ? mapSheetEntity.getMapidNm() : "") .detectionYear( (mapSheetAnalDataInferenceGeomEntityEntity.getCompareYyyy() != null @@ -381,8 +412,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport ? mapSheetAnalDataInferenceGeomEntityEntity.getTargetYyyy() : 0)) .beforeClass( - com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.ClassificationInfo - .builder() + ClassificationInfo.builder() .classification( mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeCd() != null ? mapSheetAnalDataInferenceGeomEntityEntity.getClassBeforeCd() @@ -393,8 +423,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport : 0.0) .build()) .afterClass( - com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.ClassificationInfo - .builder() + ClassificationInfo.builder() .classification( mapSheetAnalDataInferenceGeomEntityEntity.getClassAfterCd() != null ? mapSheetAnalDataInferenceGeomEntityEntity.getClassAfterCd() @@ -419,8 +448,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport .build(); var inspectionResultInfo = - com.kamco.cd.kamcoback.trainingdata.dto.TrainingDataLabelDto.InspectionResultInfo - .builder() + InspectionResultInfo.builder() .verificationResult(convertInspectState(assignment.toDto().getInspectState())) .inappropriateReason("") // .memo(assignment.toDto().getInspectMemo() != null ? @@ -428,7 +456,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport .build(); // 6. Geometry를 GeoJSON으로 변환 - com.fasterxml.jackson.databind.JsonNode geomJson = null; + JsonNode geomJson = null; if (mapSheetAnalDataInferenceGeomEntityEntity.getGeom() != null) { try { String geomString = @@ -443,8 +471,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport .fetchOne(); if (geomString != null) { - com.fasterxml.jackson.databind.ObjectMapper mapper = - new com.fasterxml.jackson.databind.ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); geomJson = mapper.readTree(geomString); } } catch (Exception e) { @@ -464,8 +491,7 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport .where(mapInkx5kEntity.mapidcdNo.eq(assignment.toDto().getAssignGroupId())) .fetchOne(); if (bboxString != null) { - com.fasterxml.jackson.databind.ObjectMapper mapper = - new com.fasterxml.jackson.databind.ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); mapBbox = mapper.readTree(bboxString); } } catch (Exception e) { @@ -473,6 +499,29 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport } } + // 7. 라벨링 저장한 Geometry를 GeoJSON으로 변환 + JsonNode learnJson = null; + try { + String learnString = + queryFactory + .select( + Expressions.stringTemplate( + "ST_AsGeoJSON({0})", mapSheetLearnDataGeomEntity.geom)) + .from(mapSheetLearnDataGeomEntity) + .where( + mapSheetLearnDataGeomEntity.geoUid.eq( + mapSheetAnalDataInferenceGeomEntityEntity.getGeoUid())) + .fetchOne(); + + if (learnString != null) { + ObjectMapper mapper = new ObjectMapper(); + learnJson = mapper.readTree(learnString); + } + } catch (Exception e) { + System.err.println("learnJson parsing error: " + e.getMessage()); + // JSON 파싱 실패 시 null 유지 + } + return DetailRes.builder() .assignmentUid(assignmentUid) .changeDetectionInfo(changeDetectionInfo) @@ -481,7 +530,9 @@ public class TrainingDataLabelRepositoryImpl extends QuerydslRepositorySupport .beforeCogUrl(beforeCogUrl) .afterCogUrl(afterCogUrl) .mapBox(mapBbox) + .learnGeometry(learnJson) .build(); + } catch (Exception e) { System.err.println("getDetail Error: " + e.getMessage()); e.printStackTrace(); diff --git a/src/main/java/com/kamco/cd/kamcoback/trainingdata/dto/TrainingDataLabelDto.java b/src/main/java/com/kamco/cd/kamcoback/trainingdata/dto/TrainingDataLabelDto.java index 88f26ff7..278cfa20 100644 --- a/src/main/java/com/kamco/cd/kamcoback/trainingdata/dto/TrainingDataLabelDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/trainingdata/dto/TrainingDataLabelDto.java @@ -211,6 +211,9 @@ public class TrainingDataLabelDto { @Schema(description = "도엽 bbox") private JsonNode mapBox; + + @Schema(description = "라벨링 툴에서 그린 폴리곤") + private JsonNode learnGeometry; } @Schema(name = "ChangeDetectionInfo", description = "변화탐지정보")