api scene test
This commit is contained in:
@@ -84,6 +84,10 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
|
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
|
||||||
implementation 'org.reflections:reflections:0.10.2'
|
implementation 'org.reflections:reflections:0.10.2'
|
||||||
|
|
||||||
|
|
||||||
|
implementation 'org.locationtech.jts:jts-core:1.19.0'
|
||||||
|
implementation 'org.locationtech.jts.io:jts-io-common:1.19.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package com.kamco.cd.kamcoback.common.geometry;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.locationtech.jts.geom.Geometry;
|
||||||
|
|
||||||
|
/** GeoJSON 파일 생성 유틸리티 */
|
||||||
|
public class GeoJsonFileWriter {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
public GeoJsonFileWriter() {
|
||||||
|
this.objectMapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoJsonFileWriter(ObjectMapper objectMapper) {
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GeoJSON 문자열 생성
|
||||||
|
*
|
||||||
|
* @param features Feature 목록
|
||||||
|
* @param name GeoJSON name 속성
|
||||||
|
* @param srid CRS EPSG 코드
|
||||||
|
* @return GeoJSON 문자열
|
||||||
|
*/
|
||||||
|
public String buildGeoJson(List<ImageFeature> features, String name, int srid) {
|
||||||
|
try {
|
||||||
|
ObjectNode root = objectMapper.createObjectNode();
|
||||||
|
root.put("type", "FeatureCollection");
|
||||||
|
root.put("name", name);
|
||||||
|
|
||||||
|
// CRS 정보
|
||||||
|
ObjectNode crs = objectMapper.createObjectNode();
|
||||||
|
crs.put("type", "name");
|
||||||
|
ObjectNode crsProps = objectMapper.createObjectNode();
|
||||||
|
crsProps.put("name", "urn:ogc:def:crs:EPSG::" + srid);
|
||||||
|
crs.set("properties", crsProps);
|
||||||
|
root.set("crs", crs);
|
||||||
|
|
||||||
|
// Features 배열
|
||||||
|
ArrayNode featuresArray = objectMapper.createArrayNode();
|
||||||
|
for (ImageFeature f : features) {
|
||||||
|
featuresArray.add(buildFeature(f));
|
||||||
|
}
|
||||||
|
root.set("features", featuresArray);
|
||||||
|
|
||||||
|
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("GeoJSON 생성 실패", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 단일 Feature 객체 생성 */
|
||||||
|
private ObjectNode buildFeature(ImageFeature f) throws Exception {
|
||||||
|
ObjectNode feature = objectMapper.createObjectNode();
|
||||||
|
feature.put("type", "Feature");
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
ObjectNode properties = objectMapper.createObjectNode();
|
||||||
|
properties.put("scene_id", f.getSceneId());
|
||||||
|
properties.put("abs_path", f.getAbsPath());
|
||||||
|
properties.put("basename", f.getFileName());
|
||||||
|
properties.put("georef_source", "internal");
|
||||||
|
properties.put("crs_source", "transformed");
|
||||||
|
feature.set("properties", properties);
|
||||||
|
|
||||||
|
// Geometry (CRS 제거)
|
||||||
|
ObjectNode geometry = (ObjectNode) objectMapper.readTree(f.getGeomJson());
|
||||||
|
geometry.remove("crs");
|
||||||
|
feature.set("geometry", geometry);
|
||||||
|
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일로 저장
|
||||||
|
*
|
||||||
|
* @param geojson GeoJSON 문자열
|
||||||
|
* @param filePath 저장 경로
|
||||||
|
*/
|
||||||
|
public void writeToFile(String geojson, String filePath) throws IOException {
|
||||||
|
try (FileWriter writer = new FileWriter(filePath)) {
|
||||||
|
writer.write(geojson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Feature 목록을 바로 파일로 저장 */
|
||||||
|
public void exportToFile(List<ImageFeature> features, String name, int srid, String filePath)
|
||||||
|
throws IOException {
|
||||||
|
String geojson = buildGeoJson(features, name, srid);
|
||||||
|
writeToFile(geojson, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Feature 데이터 클래스 */
|
||||||
|
public static class ImageFeature {
|
||||||
|
|
||||||
|
private String sceneId;
|
||||||
|
private String filePath;
|
||||||
|
private String fileName;
|
||||||
|
private String geomJson;
|
||||||
|
|
||||||
|
public ImageFeature() {}
|
||||||
|
|
||||||
|
public ImageFeature(String sceneId, String filePath, String fileName, Geometry geomJson) {
|
||||||
|
this.sceneId = sceneId;
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.fileName = fileName;
|
||||||
|
if (geomJson != null) {
|
||||||
|
|
||||||
|
this.geomJson = GeometryUtils.toGeoJson(geomJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSceneId() {
|
||||||
|
return sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSceneId(String sceneId) {
|
||||||
|
this.sceneId = sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilePath() {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilePath(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGeomJson() {
|
||||||
|
return geomJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGeomJson(String geomJson) {
|
||||||
|
this.geomJson = geomJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAbsPath() {
|
||||||
|
return filePath + "/" + fileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.kamco.cd.kamcoback.common.geometry;
|
||||||
|
|
||||||
|
import org.locationtech.jts.geom.Geometry;
|
||||||
|
import org.locationtech.jts.io.geojson.GeoJsonWriter;
|
||||||
|
|
||||||
|
public class GeometryUtils {
|
||||||
|
|
||||||
|
private static final GeoJsonWriter GEOJSON_WRITER = new GeoJsonWriter(8);
|
||||||
|
|
||||||
|
/** JTS Geometry를 GeoJSON 문자열로 변환 */
|
||||||
|
public static String toGeoJson(Geometry geometry) {
|
||||||
|
if (geometry == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return GEOJSON_WRITER.write(geometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,7 +116,9 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
// 업로드 파일 사이즈,확장자명 체크
|
// 업로드 파일 사이즈,확장자명 체크
|
||||||
dmlReturn = this.validationFile(tfwFile, tifFile);
|
dmlReturn = this.validationFile(tfwFile, tifFile);
|
||||||
if (dmlReturn.getFlag().equals("fail")) return dmlReturn;
|
if (dmlReturn.getFlag().equals("fail")) {
|
||||||
|
return dmlReturn;
|
||||||
|
}
|
||||||
|
|
||||||
MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy());
|
MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy());
|
||||||
String targetYearDir = mngDto.getMngPath();
|
String targetYearDir = mngDto.getMngPath();
|
||||||
@@ -126,20 +128,28 @@ public class MapSheetMngService {
|
|||||||
dmlReturn =
|
dmlReturn =
|
||||||
this.duplicateFile(
|
this.duplicateFile(
|
||||||
errDto.getMngYyyy(), tfwFile.getOriginalFilename(), tifFile.getOriginalFilename());
|
errDto.getMngYyyy(), tfwFile.getOriginalFilename(), tifFile.getOriginalFilename());
|
||||||
if (dmlReturn.getFlag().equals("duplicate")) return dmlReturn;
|
if (dmlReturn.getFlag().equals("duplicate")) {
|
||||||
|
return dmlReturn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 멀티파트 파일 tmp폴더 저장(파일형식 체크를 위해)
|
// 멀티파트 파일 tmp폴더 저장(파일형식 체크를 위해)
|
||||||
String tfwTmpPath = tmpPath + tfwFile.getOriginalFilename();
|
String tfwTmpPath = tmpPath + tfwFile.getOriginalFilename();
|
||||||
String tifTmpPath = tmpPath + tifFile.getOriginalFilename();
|
String tifTmpPath = tmpPath + tifFile.getOriginalFilename();
|
||||||
|
|
||||||
if (!FIleChecker.multipartSaveTo(tfwFile, tfwTmpPath))
|
if (!FIleChecker.multipartSaveTo(tfwFile, tfwTmpPath)) {
|
||||||
return new DmlReturn("fail", "UPLOAD ERROR");
|
return new DmlReturn("fail", "UPLOAD ERROR");
|
||||||
if (!FIleChecker.multipartSaveTo(tifFile, tifTmpPath))
|
}
|
||||||
|
if (!FIleChecker.multipartSaveTo(tifFile, tifTmpPath)) {
|
||||||
return new DmlReturn("fail", "UPLOAD ERROR");
|
return new DmlReturn("fail", "UPLOAD ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) return new DmlReturn("fail", "TIF TYPE ERROR");
|
if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) {
|
||||||
if (!FIleChecker.checkTfw(tfwTmpPath)) return new DmlReturn("fail", "TFW TYPE ERROR");
|
return new DmlReturn("fail", "TIF TYPE ERROR");
|
||||||
|
}
|
||||||
|
if (!FIleChecker.checkTfw(tfwTmpPath)) {
|
||||||
|
return new DmlReturn("fail", "TFW TYPE ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
// 싱크파일목록으로 업로드 경로 확인
|
// 싱크파일목록으로 업로드 경로 확인
|
||||||
List<MngFilesDto> mngFiles = mapSheetMngCoreService.findByHstUidMapSheetFileList(hstUid);
|
List<MngFilesDto> mngFiles = mapSheetMngCoreService.findByHstUidMapSheetFileList(hstUid);
|
||||||
@@ -232,8 +242,11 @@ public class MapSheetMngService {
|
|||||||
reqDto.setFilePath(dto.getFilePath());
|
reqDto.setFilePath(dto.getFilePath());
|
||||||
reqDto.setSyncCheckState("DONE");
|
reqDto.setSyncCheckState("DONE");
|
||||||
|
|
||||||
if (dto.getFileExt().equals("tif")) reqDto.setSyncCheckTifFileName(dto.getFileName());
|
if (dto.getFileExt().equals("tif")) {
|
||||||
else if (dto.getFileExt().equals("tfw")) reqDto.setSyncCheckTfwFileName(dto.getFileName());
|
reqDto.setSyncCheckTifFileName(dto.getFileName());
|
||||||
|
} else if (dto.getFileExt().equals("tfw")) {
|
||||||
|
reqDto.setSyncCheckTfwFileName(dto.getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
mapSheetMngCoreService.updateByFileUidFileState(uid, "DONE");
|
mapSheetMngCoreService.updateByFileUidFileState(uid, "DONE");
|
||||||
}
|
}
|
||||||
@@ -247,12 +260,15 @@ public class MapSheetMngService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DmlReturn validationFile(MultipartFile tfwFile, MultipartFile tifFile) {
|
public DmlReturn validationFile(MultipartFile tfwFile, MultipartFile tifFile) {
|
||||||
if (!FIleChecker.validationMultipart(tfwFile)) return new DmlReturn("fail", "TFW SIZE 오류");
|
if (!FIleChecker.validationMultipart(tfwFile)) {
|
||||||
else if (!FIleChecker.validationMultipart(tifFile)) return new DmlReturn("fail", "TFW SIZE 오류");
|
return new DmlReturn("fail", "TFW SIZE 오류");
|
||||||
else if (!FIleChecker.checkExtensions(tfwFile.getOriginalFilename(), "tfw"))
|
} else if (!FIleChecker.validationMultipart(tifFile)) {
|
||||||
|
return new DmlReturn("fail", "TFW SIZE 오류");
|
||||||
|
} else if (!FIleChecker.checkExtensions(tfwFile.getOriginalFilename(), "tfw")) {
|
||||||
return new DmlReturn("fail", "TFW FILENAME ERROR");
|
return new DmlReturn("fail", "TFW FILENAME ERROR");
|
||||||
else if (!FIleChecker.checkExtensions(tifFile.getOriginalFilename(), "tif"))
|
} else if (!FIleChecker.checkExtensions(tifFile.getOriginalFilename(), "tif")) {
|
||||||
return new DmlReturn("fail", "TIF FILENAME ERROR");
|
return new DmlReturn("fail", "TIF FILENAME ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
return new DmlReturn("success", "파일체크");
|
return new DmlReturn("success", "파일체크");
|
||||||
}
|
}
|
||||||
@@ -263,11 +279,16 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
if (tfwCnt > 0 || tifCnt > 0) {
|
if (tfwCnt > 0 || tifCnt > 0) {
|
||||||
String resMsg = "";
|
String resMsg = "";
|
||||||
if (tfwCnt > 0) resMsg = tfwFileName;
|
if (tfwCnt > 0) {
|
||||||
|
resMsg = tfwFileName;
|
||||||
|
}
|
||||||
|
|
||||||
if (tifCnt > 0) {
|
if (tifCnt > 0) {
|
||||||
if (tfwCnt > 0) resMsg = resMsg + "," + tifFileName;
|
if (tfwCnt > 0) {
|
||||||
else resMsg = tifFileName;
|
resMsg = resMsg + "," + tifFileName;
|
||||||
|
} else {
|
||||||
|
resMsg = tifFileName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new DmlReturn("duplicate", resMsg);
|
return new DmlReturn("duplicate", resMsg);
|
||||||
}
|
}
|
||||||
@@ -313,4 +334,8 @@ public class MapSheetMngService {
|
|||||||
|
|
||||||
return new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
return new FilesDto(dirPath, fileTotCnt, fileTotSize, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getSceneInference(String yyyy) {
|
||||||
|
mapSheetMngCoreService.getSceneInference(yyyy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.kamco.cd.kamcoback.postgres.core;
|
package com.kamco.cd.kamcoback.postgres.core;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter;
|
||||||
|
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.ImageFeature;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngEntity;
|
||||||
@@ -8,24 +10,33 @@ import com.kamco.cd.kamcoback.postgres.entity.YearEntity;
|
|||||||
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
|
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
|
||||||
import jakarta.persistence.EntityNotFoundException;
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MapSheetMngCoreService {
|
public class MapSheetMngCoreService {
|
||||||
|
|
||||||
private final MapSheetMngRepository mapSheetMngRepository;
|
private final MapSheetMngRepository mapSheetMngRepository;
|
||||||
|
|
||||||
@Value("{spring.profiles.active}")
|
@Value("${spring.profiles.active}")
|
||||||
private String activeEnv;
|
private String activeEnv;
|
||||||
|
|
||||||
|
@Value("${file.sync-root-dir}")
|
||||||
|
private String syncRootDir;
|
||||||
|
|
||||||
public List<MapSheetMngDto.MngDto> findMapSheetMngList() {
|
public List<MapSheetMngDto.MngDto> findMapSheetMngList() {
|
||||||
return mapSheetMngRepository.findMapSheetMngList();
|
return mapSheetMngRepository.findMapSheetMngList();
|
||||||
}
|
}
|
||||||
@@ -145,4 +156,48 @@ public class MapSheetMngCoreService {
|
|||||||
public void deleteByNotInFileUidMngFile(Long hstUid, List<Long> fileUids) {
|
public void deleteByNotInFileUidMngFile(Long hstUid, List<Long> fileUids) {
|
||||||
mapSheetMngRepository.deleteByNotInFileUidMngFile(hstUid, fileUids);
|
mapSheetMngRepository.deleteByNotInFileUidMngFile(hstUid, fileUids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 추론용 장면 데이터를 GeoJSON 파일로 내보내기
|
||||||
|
*
|
||||||
|
* @param yyyy 연도
|
||||||
|
*/
|
||||||
|
public void getSceneInference(String yyyy) {
|
||||||
|
try {
|
||||||
|
List<String> scenes =
|
||||||
|
Arrays.asList(
|
||||||
|
"34602060",
|
||||||
|
"35615072",
|
||||||
|
"35813026",
|
||||||
|
"35813027",
|
||||||
|
"35813028",
|
||||||
|
"35813029",
|
||||||
|
"35813021",
|
||||||
|
"35813030",
|
||||||
|
"35813022");
|
||||||
|
List<ImageFeature> sceneInference = mapSheetMngRepository.getSceneInference(yyyy, scenes);
|
||||||
|
|
||||||
|
if (sceneInference == null || sceneInference.isEmpty()) {
|
||||||
|
log.warn("No scene data found for year: {}", yyyy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String filename = String.format("%s_%s.geojson", yyyy, activeEnv);
|
||||||
|
String outputPath = Paths.get(syncRootDir, filename).toString();
|
||||||
|
|
||||||
|
// 디렉토리가 없으면 생성
|
||||||
|
Files.createDirectories(Paths.get(syncRootDir));
|
||||||
|
|
||||||
|
// GeoJSON 파일 생성 (EPSG:5186 - Korea 2000 / Central Belt 2010)
|
||||||
|
GeoJsonFileWriter writer = new GeoJsonFileWriter();
|
||||||
|
writer.exportToFile(sceneInference, "scene_inference_" + yyyy, 5186, outputPath);
|
||||||
|
|
||||||
|
log.info("GeoJSON file created successfully: {}", outputPath);
|
||||||
|
log.info("Total features exported: {}", sceneInference.size());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Failed to create GeoJSON file for year: {}", yyyy, e);
|
||||||
|
throw new RuntimeException("GeoJSON 파일 생성 실패: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
|
package com.kamco.cd.kamcoback.postgres.repository.mapsheet;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.ImageFeature;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
|
||||||
@@ -65,4 +66,6 @@ public interface MapSheetMngRepositoryCustom {
|
|||||||
int findByYearFileNameFileCount(int mngYyyy, String fileName);
|
int findByYearFileNameFileCount(int mngYyyy, String fileName);
|
||||||
|
|
||||||
Page<YearEntity> getYears(YearSearchReq req);
|
Page<YearEntity> getYears(YearSearchReq req);
|
||||||
|
|
||||||
|
List<ImageFeature> getSceneInference(String yyyy, List<String> mapSheetNums);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngFileEntity.mapS
|
|||||||
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity;
|
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetMngHstEntity.mapSheetMngHstEntity;
|
||||||
import static com.kamco.cd.kamcoback.postgres.entity.QYearEntity.yearEntity;
|
import static com.kamco.cd.kamcoback.postgres.entity.QYearEntity.yearEntity;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.common.geometry.GeoJsonFileWriter.ImageFeature;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
|
||||||
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.YearSearchReq;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
|
||||||
@@ -819,6 +820,43 @@ public class MapSheetMngRepositoryImpl extends QuerydslRepositorySupport
|
|||||||
return new PageImpl<>(content, pageable, total);
|
return new PageImpl<>(content, pageable, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ImageFeature> getSceneInference(String yyyy, List<String> mapSheetNums) {
|
||||||
|
BooleanBuilder whereBuilder = new BooleanBuilder();
|
||||||
|
|
||||||
|
// sync_state = 'DONE'
|
||||||
|
whereBuilder.and(mapSheetMngHstEntity.syncState.eq("DONE"));
|
||||||
|
|
||||||
|
// file_ext = 'tif'
|
||||||
|
whereBuilder.and(mapSheetMngFileEntity.fileExt.eq("tif"));
|
||||||
|
|
||||||
|
// mng_yyyy = '2023'
|
||||||
|
if (yyyy != null && !yyyy.isEmpty()) {
|
||||||
|
whereBuilder.and(mapSheetMngHstEntity.mngYyyy.eq(Integer.parseInt(yyyy)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapidcd_no in (...)
|
||||||
|
if (mapSheetNums != null && !mapSheetNums.isEmpty()) {
|
||||||
|
whereBuilder.and(mapInkx5kEntity.mapidcdNo.in(mapSheetNums));
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryFactory
|
||||||
|
.select(
|
||||||
|
Projections.constructor(
|
||||||
|
ImageFeature.class,
|
||||||
|
mapSheetMngHstEntity.mapSheetNum,
|
||||||
|
mapSheetMngFileEntity.filePath,
|
||||||
|
mapSheetMngFileEntity.fileName,
|
||||||
|
mapInkx5kEntity.geom))
|
||||||
|
.from(mapSheetMngHstEntity)
|
||||||
|
.innerJoin(mapSheetMngFileEntity)
|
||||||
|
.on(mapSheetMngHstEntity.hstUid.eq(mapSheetMngFileEntity.hstUid))
|
||||||
|
.innerJoin(mapSheetMngHstEntity.mapInkx5kByCode, mapInkx5kEntity)
|
||||||
|
.where(whereBuilder)
|
||||||
|
.orderBy(mapSheetMngHstEntity.mapSheetNum.desc())
|
||||||
|
.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
private BooleanExpression eqYearStatus(QYearEntity years, String status) {
|
private BooleanExpression eqYearStatus(QYearEntity years, String status) {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
package com.kamco.cd.kamcoback.scene;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
import com.kamco.cd.kamcoback.auth.JwtTokenProvider;
|
|
||||||
import com.kamco.cd.kamcoback.common.enums.CommonUseStatus;
|
|
||||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
|
|
||||||
import com.kamco.cd.kamcoback.menu.service.MenuService;
|
|
||||||
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
|
|
||||||
import com.kamco.cd.kamcoback.postgres.repository.log.ErrorLogRepository;
|
|
||||||
import com.kamco.cd.kamcoback.scene.dto.MapInkxMngDto;
|
|
||||||
import com.kamco.cd.kamcoback.scene.service.MapInkxMngService;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
|
|
||||||
@WebMvcTest(MapInkxMngApiV2Controller.class)
|
|
||||||
@AutoConfigureMockMvc(addFilters = false)
|
|
||||||
class MapInkxMngApiV2ControllerTest {
|
|
||||||
|
|
||||||
@Autowired private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@MockitoBean private MapInkxMngService mapInkxMngService;
|
|
||||||
|
|
||||||
@MockitoBean private JwtTokenProvider jwtTokenProvider;
|
|
||||||
|
|
||||||
@MockitoBean private ErrorLogRepository errorLogRepository;
|
|
||||||
|
|
||||||
@MockitoBean private AuditLogRepository auditLogRepository;
|
|
||||||
|
|
||||||
@MockitoBean private MenuService menuService;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("도엽 목록 조회 - 기본 파라미터")
|
|
||||||
void findMapInkxMngList_withDefaultParams() throws Exception {
|
|
||||||
// Given
|
|
||||||
InferenceResultDto.MapSheet scene50k = new InferenceResultDto.MapSheet("36713", "논산");
|
|
||||||
InferenceResultDto.MapSheet scene5k1 = new InferenceResultDto.MapSheet("36713029", "논산");
|
|
||||||
InferenceResultDto.MapSheet scene5k2 = new InferenceResultDto.MapSheet("36713085", "논산");
|
|
||||||
|
|
||||||
MapInkxMngDto.MapListEntity entity1 =
|
|
||||||
MapInkxMngDto.MapListEntity.builder()
|
|
||||||
.scene50k(scene50k)
|
|
||||||
.scene5k(scene5k1)
|
|
||||||
.useInference(CommonUseStatus.USE)
|
|
||||||
.createdDttm(ZonedDateTime.now())
|
|
||||||
.updatedDttm(ZonedDateTime.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
MapInkxMngDto.MapListEntity entity2 =
|
|
||||||
MapInkxMngDto.MapListEntity.builder()
|
|
||||||
.scene50k(scene50k)
|
|
||||||
.scene5k(scene5k2)
|
|
||||||
.useInference(CommonUseStatus.USE)
|
|
||||||
.createdDttm(ZonedDateTime.now())
|
|
||||||
.updatedDttm(ZonedDateTime.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Page<MapInkxMngDto.MapListEntity> page =
|
|
||||||
new PageImpl<>(List.of(entity1, entity2), PageRequest.of(0, 20), 2);
|
|
||||||
|
|
||||||
when(mapInkxMngService.findMapInkxMngLists(eq(null), eq(null), any())).thenReturn(page);
|
|
||||||
|
|
||||||
// When & Then
|
|
||||||
mockMvc
|
|
||||||
.perform(get("/api/v2/scene"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.data.content").isArray())
|
|
||||||
.andExpect(jsonPath("$.data.content[0].scene5k.number").value("36713029"))
|
|
||||||
.andExpect(jsonPath("$.data.content[0].scene5k.name").value("논산"))
|
|
||||||
.andExpect(jsonPath("$.data.content[1].scene5k.number").value("36713085"))
|
|
||||||
.andExpect(jsonPath("$.data.totalElements").value(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("도엽 목록 조회 - useInference 파라미터 포함")
|
|
||||||
void findMapInkxMngList_withUseInferenceParam() throws Exception {
|
|
||||||
// Given
|
|
||||||
InferenceResultDto.MapSheet scene50k = new InferenceResultDto.MapSheet("36713", "논산");
|
|
||||||
InferenceResultDto.MapSheet scene5k = new InferenceResultDto.MapSheet("36713029", "논산");
|
|
||||||
|
|
||||||
MapInkxMngDto.MapListEntity entity =
|
|
||||||
MapInkxMngDto.MapListEntity.builder()
|
|
||||||
.scene50k(scene50k)
|
|
||||||
.scene5k(scene5k)
|
|
||||||
.useInference(CommonUseStatus.EXCEPT)
|
|
||||||
.createdDttm(ZonedDateTime.now())
|
|
||||||
.updatedDttm(ZonedDateTime.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Page<MapInkxMngDto.MapListEntity> page =
|
|
||||||
new PageImpl<>(List.of(entity), PageRequest.of(0, 20), 1);
|
|
||||||
|
|
||||||
when(mapInkxMngService.findMapInkxMngLists(eq(CommonUseStatus.EXCEPT), eq(null), any()))
|
|
||||||
.thenReturn(page);
|
|
||||||
|
|
||||||
// When & Then
|
|
||||||
mockMvc
|
|
||||||
.perform(get("/api/v2/scene").param("useInference", "EXCEPT"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.data.content").isArray())
|
|
||||||
.andExpect(jsonPath("$.data.content[0].useInference.id").value("EXCEPT"))
|
|
||||||
.andExpect(jsonPath("$.data.totalElements").value(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("도엽 목록 조회 - searchVal 파라미터로 검색")
|
|
||||||
void findMapInkxMngList_withSearchVal() throws Exception {
|
|
||||||
// Given
|
|
||||||
InferenceResultDto.MapSheet scene50k = new InferenceResultDto.MapSheet("36713029", "공덕");
|
|
||||||
InferenceResultDto.MapSheet scene5k = new InferenceResultDto.MapSheet("31540687", "공덕");
|
|
||||||
|
|
||||||
MapInkxMngDto.MapListEntity entity =
|
|
||||||
MapInkxMngDto.MapListEntity.builder()
|
|
||||||
.scene50k(scene50k)
|
|
||||||
.scene5k(scene5k)
|
|
||||||
.useInference(CommonUseStatus.USE)
|
|
||||||
.createdDttm(ZonedDateTime.now())
|
|
||||||
.updatedDttm(ZonedDateTime.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Page<MapInkxMngDto.MapListEntity> page =
|
|
||||||
new PageImpl<>(List.of(entity), PageRequest.of(0, 20), 1);
|
|
||||||
|
|
||||||
when(mapInkxMngService.findMapInkxMngLists(eq(null), eq("공덕"), any())).thenReturn(page);
|
|
||||||
|
|
||||||
// When & Then
|
|
||||||
mockMvc
|
|
||||||
.perform(get("/api/v2/scene").param("searchVal", "공덕"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.data.content[0].scene5k.name").value("공덕"))
|
|
||||||
.andExpect(jsonPath("$.data.totalElements").value(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("도엽 목록 조회 - 페이징 파라미터")
|
|
||||||
void findMapInkxMngList_withPagingParams() throws Exception {
|
|
||||||
// Given
|
|
||||||
Page<MapInkxMngDto.MapListEntity> page = new PageImpl<>(List.of(), PageRequest.of(1, 10), 0);
|
|
||||||
|
|
||||||
when(mapInkxMngService.findMapInkxMngLists(eq(null), eq(null), any())).thenReturn(page);
|
|
||||||
|
|
||||||
// When & Then
|
|
||||||
mockMvc
|
|
||||||
.perform(get("/api/v2/scene").param("page", "1").param("size", "10"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.data.pageable.pageNumber").value(1))
|
|
||||||
.andExpect(jsonPath("$.data.pageable.pageSize").value(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("도엽 목록 조회 - 모든 파라미터 포함")
|
|
||||||
void findMapInkxMngList_withAllParams() throws Exception {
|
|
||||||
// Given
|
|
||||||
InferenceResultDto.MapSheet scene50k = new InferenceResultDto.MapSheet("31540", "공덕");
|
|
||||||
InferenceResultDto.MapSheet scene5k = new InferenceResultDto.MapSheet("31540687", "공덕");
|
|
||||||
|
|
||||||
MapInkxMngDto.MapListEntity entity =
|
|
||||||
MapInkxMngDto.MapListEntity.builder()
|
|
||||||
.scene50k(scene50k)
|
|
||||||
.scene5k(scene5k)
|
|
||||||
.useInference(CommonUseStatus.USE)
|
|
||||||
.createdDttm(ZonedDateTime.now())
|
|
||||||
.updatedDttm(ZonedDateTime.now())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Page<MapInkxMngDto.MapListEntity> page =
|
|
||||||
new PageImpl<>(List.of(entity), PageRequest.of(0, 5), 1);
|
|
||||||
|
|
||||||
when(mapInkxMngService.findMapInkxMngLists(eq(CommonUseStatus.USE), eq("공덕"), any()))
|
|
||||||
.thenReturn(page);
|
|
||||||
|
|
||||||
// When & Then
|
|
||||||
mockMvc
|
|
||||||
.perform(
|
|
||||||
get("/api/v2/scene")
|
|
||||||
.param("page", "0")
|
|
||||||
.param("size", "5")
|
|
||||||
.param("useInference", "USE")
|
|
||||||
.param("searchVal", "공덕"))
|
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.data.content[0].scene5k.number").value("31540687"))
|
|
||||||
.andExpect(jsonPath("$.data.content[0].scene5k.name").value("공덕"))
|
|
||||||
.andExpect(jsonPath("$.data.content[0].useInference.id").value("USE"))
|
|
||||||
.andExpect(jsonPath("$.data.totalElements").value(1))
|
|
||||||
.andExpect(jsonPath("$.data.pageable.pageSize").value(5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user