이노펨 목업 수정

This commit is contained in:
2025-12-31 11:07:21 +09:00
parent 1d3e4f22cb
commit ce87fbfc13
2 changed files with 72 additions and 40 deletions

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.FeaturePnuDto;
import com.kamco.cd.kamcoback.Innopam.service.DetectMastService; import com.kamco.cd.kamcoback.Innopam.service.DetectMastService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -126,20 +127,26 @@ public class InnopamApiController {
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}") @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}")
public void selectPnuList( public List<FeaturePnuDto> selectPnuList(
@PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable String dtctSno) { @PathVariable String cprsBfYr, @PathVariable String cprsAfYr, @PathVariable String dtctSno) {
DetectMastSearch detectMastSearch = new DetectMastSearch(); DetectMastSearch detectMastSearch = new DetectMastSearch();
detectMastSearch.setCprsAdYr(cprsAfYr); detectMastSearch.setCprsAdYr(cprsAfYr);
detectMastSearch.setCprsBfYr(cprsBfYr); detectMastSearch.setCprsBfYr(cprsBfYr);
detectMastSearch.setDtctSno(Integer.parseInt(dtctSno)); detectMastSearch.setDtctSno(Integer.parseInt(dtctSno));
detectMastService.findPnuData(detectMastSearch); return detectMastService.findPnuData(detectMastSearch);
} }
/**
* 탐지객체 PNU 단건 조회
*
* @param detectMast
*/
@GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}/{featureId}") @GetMapping("/pnu/{cprsBfYr}/{cprsAfYr}/{dtctSno}/{featureId}")
public void selectPnuDetail(@RequestBody DetectMastDto detectMast) {} public FeaturePnuDto selectPnuDetail(
@PathVariable String cprsBfYr,
@PathVariable String cprsAfYr,
@PathVariable String dtctSno,
@PathVariable String featureId) {
DetectMastSearch detectMastSearch = new DetectMastSearch();
detectMastSearch.setCprsAdYr(cprsAfYr);
detectMastSearch.setCprsBfYr(cprsBfYr);
detectMastSearch.setDtctSno(Integer.parseInt(dtctSno));
detectMastSearch.setFeatureId(featureId);
return detectMastService.findPnuDataDetail(detectMastSearch);
}
} }

View File

@@ -1,17 +1,23 @@
package com.kamco.cd.kamcoback.Innopam.service; package com.kamco.cd.kamcoback.Innopam.service;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.Basic;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastReq;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.DetectMastSearch;
import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.FeaturePnuDto; import com.kamco.cd.kamcoback.Innopam.dto.DetectMastDto.FeaturePnuDto;
import com.kamco.cd.kamcoback.Innopam.postgres.core.DetectMastCoreService; import com.kamco.cd.kamcoback.Innopam.postgres.core.DetectMastCoreService;
import java.io.File; import java.io.InputStream;
import java.io.IOException; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -21,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor @RequiredArgsConstructor
public class DetectMastService { public class DetectMastService {
private final JsonFactory factory = new JsonFactory();
private final DetectMastCoreService detectMastCoreService; private final DetectMastCoreService detectMastCoreService;
@Transactional @Transactional
@@ -36,11 +43,15 @@ public class DetectMastService {
return detectMastCoreService.selectDetectMast(id); return detectMastCoreService.selectDetectMast(id);
} }
public void findPnuData(DetectMastSearch detectMast) { public List<FeaturePnuDto> findPnuData(DetectMastSearch detectMast) {
// String pathNm = detectMastCoreService.findPnuData(detectMast); String pathNm = detectMastCoreService.findPnuData(detectMast);
String pathNm = "/Users/bokmin/detect/result/2023_2024/4"; return this.extractFeaturePnusFast(pathNm);
File geoJson = new File(pathNm); }
List<FeaturePnuDto> list = this.extractFeaturePnus(geoJson);
public FeaturePnuDto findPnuDataDetail(DetectMastSearch detectMast) {
String pathNm = detectMastCoreService.findPnuData(detectMast);
List<FeaturePnuDto> pnu = this.extractFeaturePnusFast(pathNm);
return pnu.get(0);
} }
private String randomPnu() { private String randomPnu() {
@@ -54,37 +65,51 @@ public class DetectMastService {
return lawCode + sanFlag + bon + bu; return lawCode + sanFlag + bon + bu;
} }
private List<FeaturePnuDto> extractFeaturePnus(File geoJsonFile) { public List<FeaturePnuDto> extractFeaturePnusFast(String dirPath) {
ObjectMapper mapper = new ObjectMapper(); Path basePath = Paths.get(dirPath);
JsonNode root = null; if (!Files.isDirectory(basePath)) {
try { System.err.println("유효하지 않은 디렉터리: " + dirPath);
mapper.readTree(geoJsonFile); return List.of();
} catch (IOException e) {
throw new RuntimeException(e);
} }
JsonNode features = root.get("features"); // 병렬로 모으기 위한 thread-safe 컬렉션
List<FeaturePnuDto> result = new ArrayList<>(); Queue<FeaturePnuDto> out = new ConcurrentLinkedQueue<>();
if (features != null && features.isArray()) { try (Stream<Path> stream = Files.walk(basePath)) {
for (JsonNode feature : features) { stream
JsonNode properties = feature.get("properties"); .filter(Files::isRegularFile)
if (properties == null) { .filter(p -> p.toString().toLowerCase().endsWith(".geojson"))
continue; .parallel() // 병렬
.forEach(
p -> {
try (InputStream in = Files.newInputStream(p);
JsonParser parser = factory.createParser(in)) {
// "polygon_id" 키를 만나면 다음 토큰 값을 읽어서 저장
while (parser.nextToken() != null) {
if (parser.currentToken() == JsonToken.FIELD_NAME
&& "polygon_id".equals(parser.getCurrentName())) {
JsonToken next = parser.nextToken(); // 값으로 이동
if (next == JsonToken.VALUE_STRING) {
String polygonId = parser.getValueAsString();
out.add(new FeaturePnuDto(polygonId, this.randomPnu()));
} }
String polygonId = properties.path("polygon_id").asText(null);
if (polygonId == null) {
continue;
}
String pnu = this.randomPnu();
result.add(new FeaturePnuDto(polygonId, pnu));
} }
} }
return result; } catch (Exception e) {
// 파일별 에러 로그는 최소화
System.err.println("파싱 실패: " + p.getFileName() + " / " + e.getMessage());
}
});
} catch (Exception e) {
System.err.println("디렉터리 탐색 실패: " + e.getMessage());
return List.of();
}
return new ArrayList<>(out);
} }
} }