Geojson Polygon DATA Operating System Build Complete - Daniel C No.5
This commit is contained in:
@@ -3,11 +3,15 @@ package com.kamco.cd.kamcoback.geojson.service;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnDataEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnDataGeomEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.MapSheetLearnDataGeomRepository;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.MapSheetLearnDataRepository;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
import org.locationtech.jts.io.geojson.GeoJsonReader;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -18,7 +22,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class GeoJsonDataService {
|
||||
|
||||
private final MapSheetLearnDataRepository mapSheetLearnDataRepository;
|
||||
private final MapSheetLearnDataGeomRepository mapSheetLearnDataGeomRepository;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final GeoJsonReader geoJsonReader = new GeoJsonReader();
|
||||
|
||||
/** GeoJSON 파일들을 데이터베이스에 저장 */
|
||||
@Transactional
|
||||
@@ -37,6 +43,11 @@ public class GeoJsonDataService {
|
||||
if (savedId != null) {
|
||||
savedIds.add(savedId);
|
||||
log.debug("GeoJSON 파일 저장 성공: {} (ID: {})", fileName, savedId);
|
||||
|
||||
// 학습 모델 결과 파일인지 확인하여 geometry 데이터 처리
|
||||
if (isLearningModelResult(fileName, geoJsonContent)) {
|
||||
processLearningModelGeometry(savedId, geoJsonContent, fileName);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("GeoJSON 파일 처리 실패: {}", fileName, e);
|
||||
@@ -163,7 +174,24 @@ public class GeoJsonDataService {
|
||||
|
||||
/** 연도 정보 추출 */
|
||||
private void setYearInformation(MapSheetLearnDataEntity entity, String fileName) {
|
||||
// 파일명에서 연도 추출 시도 (예: kamco_2021_2022_35813023.geojson)
|
||||
// 학습 모델 결과 파일인지 확인하고 특별 처리
|
||||
if (fileName.matches(".*캠코_\\d{4}_\\d{4}_\\d+.*")) {
|
||||
String[] parts = fileName.split("_");
|
||||
if (parts.length >= 4) {
|
||||
String beforeYear = parts[1];
|
||||
String afterYear = parts[2];
|
||||
// 비교년도 정보를 첫 번째 연도의 정수로 저장
|
||||
try {
|
||||
entity.setCompareYyyy(Integer.parseInt(beforeYear));
|
||||
log.debug("학습 모델 연도 정보 설정: {}", beforeYear);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("연도 파싱 실패: {}", beforeYear, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 기존 로직: 파일명에서 연도 추출 시도
|
||||
String[] parts = fileName.split("_");
|
||||
for (String part : parts) {
|
||||
if (part.matches("\\d{4}")) { // 4자리 숫자 (연도)
|
||||
@@ -226,4 +254,177 @@ public class GeoJsonDataService {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 학습 모델 결과 파일인지 확인 */
|
||||
private boolean isLearningModelResult(String fileName, String geoJsonContent) {
|
||||
try {
|
||||
// 파일명으로 확인 (캠코_YYYY_YYYY_번호 패턴)
|
||||
if (fileName.matches(".*캠코_\\d{4}_\\d{4}_\\d+.*\\.geojson")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// GeoJSON 내용으로 확인 (학습 모델 특화 필드 존재 여부)
|
||||
JsonNode rootNode = objectMapper.readTree(geoJsonContent);
|
||||
if (rootNode.has("features")) {
|
||||
JsonNode features = rootNode.get("features");
|
||||
if (features.isArray() && features.size() > 0) {
|
||||
JsonNode firstFeature = features.get(0);
|
||||
if (firstFeature.has("properties")) {
|
||||
JsonNode properties = firstFeature.get("properties");
|
||||
// 학습 모델 특화 필드 확인
|
||||
return properties.has("cd_prob")
|
||||
|| properties.has("class")
|
||||
|| (properties.has("before") && properties.has("after"));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("학습 모델 결과 파일 확인 중 오류: {}", fileName, e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 학습 모델 결과의 geometry 데이터 처리 */
|
||||
@Transactional
|
||||
public void processLearningModelGeometry(Long dataUid, String geoJsonContent, String fileName) {
|
||||
try {
|
||||
log.info("학습 모델 geometry 데이터 처리 시작: {} (dataUid: {})", fileName, dataUid);
|
||||
|
||||
JsonNode rootNode = objectMapper.readTree(geoJsonContent);
|
||||
|
||||
// 메타데이터 추출
|
||||
String mapSheetName =
|
||||
rootNode.has("name") ? rootNode.get("name").asText() : fileName.replace(".geojson", "");
|
||||
|
||||
// 파일명에서 연도 및 지도번호 추출 (캠코_2021_2022_35813023)
|
||||
String[] parts = mapSheetName.split("_");
|
||||
String beforeYear = null, afterYear = null, mapSheetNum = null;
|
||||
|
||||
if (parts.length >= 4) {
|
||||
beforeYear = parts[1];
|
||||
afterYear = parts[2];
|
||||
mapSheetNum = parts[3];
|
||||
}
|
||||
|
||||
if (beforeYear == null || afterYear == null) {
|
||||
log.warn("연도 정보를 추출할 수 없습니다: {}", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonNode features = rootNode.get("features");
|
||||
if (features == null || !features.isArray()) {
|
||||
log.warn("features 배열이 없습니다: {}", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
List<MapSheetLearnDataGeomEntity> geomEntities = new ArrayList<>();
|
||||
int processedCount = 0;
|
||||
|
||||
for (JsonNode feature : features) {
|
||||
try {
|
||||
MapSheetLearnDataGeomEntity geomEntity =
|
||||
createGeometryEntity(feature, dataUid, beforeYear, afterYear, mapSheetNum);
|
||||
if (geomEntity != null) {
|
||||
geomEntities.add(geomEntity);
|
||||
processedCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Feature geometry 처리 실패 (feature {}): {}", processedCount, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 배치 저장
|
||||
if (!geomEntities.isEmpty()) {
|
||||
mapSheetLearnDataGeomRepository.saveAll(geomEntities);
|
||||
log.info("학습 모델 geometry 데이터 저장 완료: {} ({}개 feature)", fileName, geomEntities.size());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("학습 모델 geometry 데이터 처리 실패: {}", fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/** 개별 feature에서 geometry entity 생성 */
|
||||
private MapSheetLearnDataGeomEntity createGeometryEntity(
|
||||
JsonNode feature, Long dataUid, String beforeYear, String afterYear, String mapSheetNum) {
|
||||
|
||||
JsonNode properties = feature.get("properties");
|
||||
JsonNode geometry = feature.get("geometry");
|
||||
|
||||
if (properties == null || geometry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MapSheetLearnDataGeomEntity entity = new MapSheetLearnDataGeomEntity();
|
||||
|
||||
// 기본 정보
|
||||
entity.setDataUid(dataUid);
|
||||
entity.setBeforeYyyy(Integer.parseInt(beforeYear));
|
||||
entity.setAfterYyyy(Integer.parseInt(afterYear));
|
||||
if (mapSheetNum != null) {
|
||||
try {
|
||||
entity.setMapSheetNum(Long.parseLong(mapSheetNum));
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("지도번호 파싱 실패: {}", mapSheetNum, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 변화 탐지 확률
|
||||
if (properties.has("cd_prob")) {
|
||||
entity.setCdProb(properties.get("cd_prob").asDouble());
|
||||
}
|
||||
|
||||
// 면적 정보
|
||||
if (properties.has("area")) {
|
||||
entity.setArea(properties.get("area").asDouble());
|
||||
}
|
||||
|
||||
// 분류 정보 처리
|
||||
if (properties.has("class")) {
|
||||
JsonNode classNode = properties.get("class");
|
||||
|
||||
// before 분류
|
||||
if (classNode.has("before") && classNode.get("before").isArray()) {
|
||||
JsonNode beforeArray = classNode.get("before");
|
||||
if (beforeArray.size() > 0) {
|
||||
JsonNode firstBefore = beforeArray.get(0);
|
||||
if (firstBefore.has("class_name")) {
|
||||
entity.setClassBeforeName(firstBefore.get("class_name").asText());
|
||||
}
|
||||
if (firstBefore.has("probability")) {
|
||||
entity.setClassBeforeProb(firstBefore.get("probability").asDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after 분류
|
||||
if (classNode.has("after") && classNode.get("after").isArray()) {
|
||||
JsonNode afterArray = classNode.get("after");
|
||||
if (afterArray.size() > 0) {
|
||||
JsonNode firstAfter = afterArray.get(0);
|
||||
if (firstAfter.has("class_name")) {
|
||||
entity.setClassAfterName(firstAfter.get("class_name").asText());
|
||||
}
|
||||
if (firstAfter.has("probability")) {
|
||||
entity.setClassAfterProb(firstAfter.get("probability").asDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// geometry 변환
|
||||
try {
|
||||
Geometry geom = geoJsonReader.read(geometry.toString());
|
||||
if (geom != null) {
|
||||
geom.setSRID(5186); // EPSG:5186
|
||||
entity.setGeom(geom);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Geometry 파싱 실패: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user