From cd0e9f4116e0497a33a49d056b71fd19c98bae9c Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Wed, 24 Dec 2025 16:00:09 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8F=84=EC=97=BD=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D,=EB=93=B1=EB=A1=9D,=EC=B6=94=EB=A1=A0?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/model/dto/ModelMngDto.java | 1 - .../postgres/core/MapInkxMngCoreService.java | 74 +++++++++ .../postgres/entity/MapInkx50kEntity.java | 21 ++- .../postgres/entity/MapInkx5kEntity.java | 21 ++- .../scene/MapInkx50kRepository.java | 7 + .../scene/MapInkx50kRepositoryCustom.java | 6 + .../scene/MapInkx50kRepositoryImpl.java | 28 ++++ .../scene/MapInkx5kRepositoryCustom.java | 11 ++ .../scene/MapInkx5kRepositoryImpl.java | 94 +++++++++++ .../scene/MapInkxMngApiController.java | 113 +++++++++++++ .../cd/kamcoback/scene/dto/MapInkxMngDto.java | 157 ++++++++++++++++++ .../scene/service/MapInkxMngService.java | 58 +++++++ 12 files changed, 587 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepository.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryCustom.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryImpl.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java diff --git a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java index ea9da363..31005da6 100644 --- a/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/model/dto/ModelMngDto.java @@ -93,7 +93,6 @@ public class ModelMngDto { @Getter @Setter @NoArgsConstructor - @AllArgsConstructor public static class ModelList { private Integer rowNum; diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java new file mode 100644 index 00000000..5a7a69fd --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/MapInkxMngCoreService.java @@ -0,0 +1,74 @@ +package com.kamco.cd.kamcoback.postgres.core; + +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; +import com.kamco.cd.kamcoback.postgres.entity.MapInkx50kEntity; +import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; +import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx50kRepository; +import com.kamco.cd.kamcoback.postgres.repository.scene.MapInkx5kRepository; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.UseInferReq; +import jakarta.persistence.EntityNotFoundException; +import jakarta.validation.Valid; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.locationtech.jts.geom.Polygon; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MapInkxMngCoreService { + + private final MapInkx5kRepository mapInkx5kRepository; + private final MapInkx50kRepository mapInkx50kRepository; + + // 목록 + public Page findMapInkxMngList( + MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + return mapInkx5kRepository.findMapInkxMngList(searchReq, useInference, searchVal); + } + + // 저장 + public ResponseObj saveMapInkx5k(MapInkxMngDto.AddMapReq req, Polygon map_polygon) { + + Long existsCount = mapInkx5kRepository.findByMapidCdNoExists(req.getMapidcdNo()); + + if (existsCount > 0) { + return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 등록된 도엽코드 입니다."); + } + + Integer fid50k = mapInkx50kRepository.findByMapidCdParentNo(req.getMapidcdNo()); + if (fid50k == null || fid50k <= 0) { + // parent도 등록 + MapInkx50kEntity parent = + new MapInkx50kEntity(req.getMapidcdNo().substring(0, 5), req.getMapidNm(), "", null); + MapInkx50kEntity result = mapInkx50kRepository.save(parent); + fid50k = result.getFid(); + } + + MapInkx5kEntity entity = + new MapInkx5kEntity( + req.getMapidcdNo(), + req.getMapidNm(), + map_polygon, + fid50k == null ? null : fid50k.longValue(), + "USE" // 기본은 USE로 + ); + + mapInkx5kRepository.save(entity); + + return new ResponseObj(ApiResponseCode.OK, ""); + } + + public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { + Optional entity = + Optional.ofNullable( + mapInkx5kRepository + .findByMapidCdNoInfo(useInferReq.getMapidcdNo()) + .orElseThrow(() -> new EntityNotFoundException("도엽정보를 찾을 수 없습니다."))); + + entity.get().updateUseInference(useInferReq.getUseInference()); + return new ResponseObj(ApiResponseCode.OK, ""); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java index 42db8c9c..95649a18 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx50kEntity.java @@ -1,7 +1,15 @@ package com.kamco.cd.kamcoback.postgres.entity; -import jakarta.persistence.*; +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.SequenceGenerator; +import jakarta.persistence.Table; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import org.locationtech.jts.geom.Geometry; @@ -9,7 +17,9 @@ import org.locationtech.jts.geom.Geometry; @Setter @Table(name = "tb_map_inkx_50k") @Entity -public class MapInkx50kEntity { +@NoArgsConstructor +public class MapInkx50kEntity extends CommonDateEntity { + @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_50k_fid_seq_gen") @SequenceGenerator( @@ -29,4 +39,11 @@ public class MapInkx50kEntity { @Column(name = "geom") private Geometry geom; + + public MapInkx50kEntity(String mapidcdNo, String mapidNm, String mapidNo, Geometry geom) { + this.mapidcdNo = mapidcdNo; + this.mapidNm = mapidNm; + this.mapidNo = mapidNo; + this.geom = geom; + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java index fe95b6d1..d2d7fdb5 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/entity/MapInkx5kEntity.java @@ -2,6 +2,7 @@ package com.kamco.cd.kamcoback.postgres.entity; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.MapSheet; +import com.kamco.cd.kamcoback.postgres.CommonDateEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -10,6 +11,7 @@ import jakarta.persistence.Id; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import org.locationtech.jts.geom.Geometry; @@ -17,7 +19,8 @@ import org.locationtech.jts.geom.Geometry; @Setter @Table(name = "tb_map_inkx_5k") @Entity -public class MapInkx5kEntity { +@NoArgsConstructor +public class MapInkx5kEntity extends CommonDateEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_5k_fid_seq_gen") @@ -39,6 +42,22 @@ public class MapInkx5kEntity { @Column(name = "fid_k50") private Long fidK50; + @Column(name = "use_inference") + private String useInference; + + public MapInkx5kEntity( + String mapidcdNo, String mapidNm, Geometry geom, Long fidK50, String useInference) { + this.mapidcdNo = mapidcdNo; + this.mapidNm = mapidNm; + this.geom = geom; + this.fidK50 = fidK50; + this.useInference = useInference; + } + + public void updateUseInference(String useInference) { + this.useInference = useInference; + } + public InferenceResultDto.MapSheet toEntity() { return new MapSheet(mapidcdNo, mapidNm); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepository.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepository.java new file mode 100644 index 00000000..5be2aaa7 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepository.java @@ -0,0 +1,7 @@ +package com.kamco.cd.kamcoback.postgres.repository.scene; + +import com.kamco.cd.kamcoback.postgres.entity.MapInkx50kEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MapInkx50kRepository + extends JpaRepository, MapInkx50kRepositoryCustom {} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryCustom.java new file mode 100644 index 00000000..88365a86 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryCustom.java @@ -0,0 +1,6 @@ +package com.kamco.cd.kamcoback.postgres.repository.scene; + +public interface MapInkx50kRepositoryCustom { + + Integer findByMapidCdParentNo(String mapidcdNo); +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryImpl.java new file mode 100644 index 00000000..53c10966 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx50kRepositoryImpl.java @@ -0,0 +1,28 @@ +package com.kamco.cd.kamcoback.postgres.repository.scene; + +import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity; + +import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; +import com.querydsl.jpa.impl.JPAQueryFactory; +import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; + +public class MapInkx50kRepositoryImpl extends QuerydslRepositorySupport + implements MapInkx50kRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public MapInkx50kRepositoryImpl(JPAQueryFactory queryFactory) { + super(MapInkx5kEntity.class); + this.queryFactory = queryFactory; + } + + @Override + public Integer findByMapidCdParentNo(String mapidcdNo) { + String parentCd = mapidcdNo.substring(0, 5); + return queryFactory + .select(mapInkx50kEntity.fid) + .from(mapInkx50kEntity) + .where(mapInkx50kEntity.mapidcdNo.eq(parentCd)) + .fetchOne(); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java index e509aaeb..b1c642cb 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryCustom.java @@ -1,9 +1,20 @@ package com.kamco.cd.kamcoback.postgres.repository.scene; import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList; import java.util.List; +import java.util.Optional; +import org.springframework.data.domain.Page; public interface MapInkx5kRepositoryCustom { List listGetScenes5k(List codes); + + Page findMapInkxMngList( + MapInkxMngDto.searchReq searchReq, String useInference, String searchVal); + + Long findByMapidCdNoExists(String mapidcdNo); + + Optional findByMapidCdNoInfo(String mapidcdNo); } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java index 21fe09ea..2f957b8a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/scene/MapInkx5kRepositoryImpl.java @@ -1,9 +1,23 @@ package com.kamco.cd.kamcoback.postgres.repository.scene; +import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx50kEntity.mapInkx50kEntity; +import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity; + import com.kamco.cd.kamcoback.postgres.entity.MapInkx5kEntity; import com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.searchReq; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport @@ -25,4 +39,84 @@ public class MapInkx5kRepositoryImpl extends QuerydslRepositorySupport .orderBy(map5k.mapidcdNo.asc()) .fetch(); } + + @Override + public Page findMapInkxMngList( + searchReq searchReq, String useInference, String searchVal) { + + Pageable pageable = searchReq.toPageable(); + List foundContent = + queryFactory + .select( + Projections.constructor( + MapInkxMngDto.MapList.class, + Expressions.numberTemplate( + Integer.class, + "row_number() over(order by {0} asc)", + mapInkx5kEntity.mapidcdNo), + mapInkx5kEntity.mapidcdNo, + mapInkx50kEntity.mapidcdNo, + mapInkx5kEntity.mapidNm, + mapInkx5kEntity.createdDate, + mapInkx5kEntity.modifiedDate, + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.createdDate), + // Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", + // mapInkx5kEntity.modifiedDate), + mapInkx5kEntity.useInference)) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(mapInkx5kEntity.mapidcdNo.asc()) + .fetch(); + + Long countQuery = + queryFactory + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .innerJoin(mapInkx50kEntity) + .on(mapInkx5kEntity.fidK50.intValue().eq(mapInkx50kEntity.fid)) + .where(searchUseInference(useInference), searchValueMapCdNm(searchVal)) + .fetchOne(); + + return new PageImpl<>(foundContent, pageable, countQuery); + } + + @Override + public Long findByMapidCdNoExists(String mapidcdNo) { + return queryFactory + .select(mapInkx5kEntity.count()) + .from(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne(); + } + + @Override + public Optional findByMapidCdNoInfo(String mapidcdNo) { + return Optional.ofNullable( + queryFactory + .selectFrom(mapInkx5kEntity) + .where(mapInkx5kEntity.mapidcdNo.eq(mapidcdNo)) + .fetchOne()); + } + + private BooleanExpression searchUseInference(String useInference) { + if (Objects.isNull(useInference)) { + return null; + } + return mapInkx5kEntity.useInference.eq(useInference); + } + + private BooleanExpression searchValueMapCdNm(String searchVal) { + if (Objects.isNull(searchVal)) { + return null; + } + return mapInkx5kEntity + .mapidcdNo + .like("%" + searchVal + "%") + .or(mapInkx5kEntity.mapidNm.like("%" + searchVal + "%")); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java new file mode 100644 index 00000000..3bb3b361 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scene/MapInkxMngApiController.java @@ -0,0 +1,113 @@ +package com.kamco.cd.kamcoback.scene; + +import com.kamco.cd.kamcoback.code.dto.CommonCodeDto; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; +import com.kamco.cd.kamcoback.scene.service.MapInkxMngService; +import io.swagger.v3.oas.annotations.Operation; +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 jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "도엽 관리", description = "도엽 관리 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/scene") +public class MapInkxMngApiController { + + private final MapInkxMngService mapInkxMngService; + + @Operation(summary = "목록 조회", description = "도엽 목록 조회") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = CommonCodeDto.Basic.class))), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping + public ApiResponseDto> findMapInkxMngList( + @RequestParam int page, + @RequestParam(defaultValue = "20") int size, + @RequestParam(required = false) String useInference, + @RequestParam(required = false) String searchVal) { + MapInkxMngDto.searchReq searchReq = new MapInkxMngDto.searchReq(page, size, ""); + return ApiResponseDto.ok( + mapInkxMngService.findMapInkxMngList(searchReq, useInference, searchVal)); + } + + @Operation(summary = "저장", description = "도엽정보를 저장 합니다.") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "201", + description = "도엽정보 저장 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ApiResponseDto.ResponseObj.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PostMapping + public ApiResponseDto saveMapInkx5k( + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "도엽정보 생성 요청 정보", + required = true, + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = MapInkxMngDto.AddMapReq.class))) + @RequestBody + @Valid + MapInkxMngDto.AddMapReq addReq) { + return ApiResponseDto.okObject(mapInkxMngService.saveMapInkx5k(addReq)); + } + + @Operation(summary = "추론제외 업데이트", description = "추론제외 업데이트 합니다.") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "201", + description = "추론제외 업데이트 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ApiResponseDto.ResponseObj.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), + @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @PutMapping("/use-inference") + public ApiResponseDto updateUseInference( + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "추론제외 업데이트 정보", + required = true, + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = MapInkxMngDto.UseInferReq.class))) + @RequestBody + @Valid + MapInkxMngDto.UseInferReq useInferReq) { + return ApiResponseDto.okObject(mapInkxMngService.updateUseInference(useInferReq)); + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java new file mode 100644 index 00000000..5c8baf05 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scene/dto/MapInkxMngDto.java @@ -0,0 +1,157 @@ +package com.kamco.cd.kamcoback.scene.dto; + +import com.fasterxml.jackson.databind.JsonNode; +import com.kamco.cd.kamcoback.common.utils.enums.CodeExpose; +import com.kamco.cd.kamcoback.common.utils.enums.EnumType; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +public class MapInkxMngDto { + + @CodeExpose + @Getter + @AllArgsConstructor + public enum UseInferenceType implements EnumType { + USE("사용중"), + EXCEPT("영구 추론제외"); + + private final String desc; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return desc; + } + } + + @Schema(name = "Basic", description = "Basic") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class Basic { + + private Integer fid; + private String mapidcdNo; + private String mapidNm; + private JsonNode geom; + private Long fidK50; + private String useInference; + private ZonedDateTime createdDttm; + private ZonedDateTime updatedDttm; + } + + @Schema(name = "MapList", description = "목록 항목") + @Getter + @Setter + @NoArgsConstructor + public static class MapList { + + private Integer rowNum; + private String mapidcdNo5k; + private String mapidcdNo50k; + private String mapidNm; + private String createdDttm; + private String updatedDttm; + private String useInference; + private ZonedDateTime createdDttmTime; + private ZonedDateTime updatedDttmTime; + + // 목록 Querydsl 에서 리턴 받는 건 생성자 기준임 -> 쿼리 컬럼 그대로 받고 여기서 Java 형변환 해서 return 하기 + public MapList( + Integer rowNum, + String mapidcdNo5k, + String mapidcdNo50k, + String mapidNm, + ZonedDateTime createdDttmTime, + ZonedDateTime updatedDttmTime, + String useInference) { + this.rowNum = rowNum; + this.mapidcdNo5k = mapidcdNo5k; + this.mapidcdNo50k = mapidcdNo50k; + this.mapidNm = mapidNm; + + DateTimeFormatter fmt = + DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("Asia/Seoul")); + this.createdDttm = fmt.format(createdDttmTime); + this.updatedDttm = fmt.format(updatedDttmTime); + this.createdDttmTime = createdDttmTime; + this.updatedDttmTime = updatedDttmTime; + this.useInference = + useInference.equals("USE") + ? UseInferenceType.USE.getDesc() + : UseInferenceType.EXCEPT.getDesc(); + } + } + + @Schema(name = "searchReq", description = "검색 요청") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class searchReq { + + // 페이징 파라미터 + private int page = 0; + private int size = 20; + private String sort; + + public Pageable toPageable() { + if (sort != null && !sort.isEmpty()) { + String[] sortParams = sort.split(","); + String property = sortParams[0]; + Sort.Direction direction = + sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC; + return PageRequest.of(page, size, Sort.by(direction, property)); + } + return PageRequest.of(page, size); + } + } + + @Schema(name = "AddMapReq", description = "등록 요청") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class AddMapReq { + + @Schema(description = "도엽번호", example = "31540687") + private String mapidcdNo; + + @Schema(description = "도엽명", example = "공덕") + private String mapidNm; + + @Schema( + description = "좌표 목록 (한 줄에 한 점, '경도 위도' 형식)", + example = + "127.17500001632317 36.17499998262991\n" + + "127.14999995475043 36.17500002877932\n" + + "127.15000004313612 36.199999984012415\n" + + "127.1750000466954 36.20000001863179") + private String coordinates; + } + + @Schema(name = "UseInferReq", description = "추론제외 업데이트 요청") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + public static class UseInferReq { + + private String mapidcdNo; + private String useInference; + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java b/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java new file mode 100644 index 00000000..b39bc323 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/scene/service/MapInkxMngService.java @@ -0,0 +1,58 @@ +package com.kamco.cd.kamcoback.scene.service; + +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ResponseObj; +import com.kamco.cd.kamcoback.postgres.core.MapInkxMngCoreService; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.MapList; +import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto.UseInferReq; +import jakarta.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LinearRing; +import org.locationtech.jts.geom.PrecisionModel; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MapInkxMngService { + + private final MapInkxMngCoreService mapInkxMngCoreService; + + public Page findMapInkxMngList( + MapInkxMngDto.searchReq searchReq, String useInference, String searchVal) { + return mapInkxMngCoreService.findMapInkxMngList(searchReq, useInference, searchVal); + } + + public ResponseObj saveMapInkx5k(@Valid MapInkxMngDto.AddMapReq req) { + + String[] coordinates = req.getCoordinates().split("\\r?\\n"); + List coords = new ArrayList(); + + for (String line : coordinates) { + String[] parts = line.trim().split("\\s+"); + + double lon = Double.parseDouble(parts[0]); // 경도 + double lat = Double.parseDouble(parts[1]); // 위도 + + coords.add(new Coordinate(lon, lat)); + } + + // Polygon은 반드시 닫혀 있어야 함 + if (!coords.get(0).equals2D(coords.get(coords.size() - 1))) { + coords.add(coords.get(0)); + } + + GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(new PrecisionModel(), 4326); + LinearRing shell = GEOMETRY_FACTORY.createLinearRing(coords.toArray(new Coordinate[0])); + + return mapInkxMngCoreService.saveMapInkx5k(req, GEOMETRY_FACTORY.createPolygon(shell)); + } + + public ResponseObj updateUseInference(@Valid UseInferReq useInferReq) { + return mapInkxMngCoreService.updateUseInference(useInferReq); + } +}