변화탐지 polygon, point 4326 으로 변환

This commit is contained in:
2025-12-01 11:06:02 +09:00
parent c40b3015c6
commit cf33d7378f
7 changed files with 136 additions and 51 deletions

View File

@@ -75,7 +75,7 @@ public class ChangeDetectionApiController {
@Operation(summary = "변화탐지 결과 Polygon", description = "변화탐지 결과 Polygon") @Operation(summary = "변화탐지 결과 Polygon", description = "변화탐지 결과 Polygon")
@GetMapping("/polygon") @GetMapping("/polygon")
public ApiResponseDto<List<ChangeDetectionDto.PolygonGeometry>> getChangeDetectionPolygonList( public ApiResponseDto<ChangeDetectionDto.PolygonFeatureList> getChangeDetectionPolygonList(
@Parameter(description = "년도목록 id", example = "1") @RequestParam Long analUid, @Parameter(description = "년도목록 id", example = "1") @RequestParam Long analUid,
@Parameter(description = "도엽번호", example = "34602060") @RequestParam String mapSheetNum) { @Parameter(description = "도엽번호", example = "34602060") @RequestParam String mapSheetNum) {
return ApiResponseDto.ok( return ApiResponseDto.ok(
@@ -84,7 +84,7 @@ public class ChangeDetectionApiController {
@Operation(summary = "변화탐지 결과 Point", description = "변화탐지 결과 Point") @Operation(summary = "변화탐지 결과 Point", description = "변화탐지 결과 Point")
@GetMapping("/point") @GetMapping("/point")
public ApiResponseDto<List<ChangeDetectionDto.PointGeometry>> getChangeDetectionPointList( public ApiResponseDto<List<ChangeDetectionDto.PointFeature>> getChangeDetectionPointList(
@Parameter(description = "년도목록 id", example = "1") @RequestParam Long analUid, @Parameter(description = "년도목록 id", example = "1") @RequestParam Long analUid,
@Parameter(description = "도엽번호", example = "34602060") @RequestParam String mapSheetNum) { @Parameter(description = "도엽번호", example = "34602060") @RequestParam String mapSheetNum) {
return ApiResponseDto.ok( return ApiResponseDto.ok(

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.kamcoback.changedetection.dto; package com.kamco.cd.kamcoback.changedetection.dto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -78,31 +79,54 @@ public class ChangeDetectionDto {
private String alias; private String alias;
} }
@Schema(name = "PolygonGeometry", description = "폴리곤 리턴 객체") @Schema(name = "PolygonFeatureList", description = "Geometry 리턴 객체")
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class PointGeometry { public static class PolygonFeatureList {
private Long geoUid; private String type;
private Geometry geometry; // Point 값 private List<PolygonFeature> features; // Point 값
private String classCd; // after 분류 private String classCd; // after 분류
} }
@Schema(name = "PolygonGeometry", description = "폴리곤 리턴 객체") @Schema(name = "PolygonFeature", description = "Geometry 리턴 객체")
@Getter @Getter
@Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class PolygonGeometry { public static class PolygonFeature {
private String type;
private Geometry geometry; // after 분류
private PolygonProperties properties; // Point 값
}
@Schema(name = "PointFeature", description = "Geometry 리턴 객체")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class PointFeature {
private String type;
private Geometry geometry; // point
private PointProperties properties; // Point 정보
}
@Schema(name = "PointProperties", description = "폴리곤 리턴 객체")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class PointProperties {
private Long geoUid; private Long geoUid;
private Geometry geometry; // Polygon 값 private String classCd; // after 분류
private PolygonProperties properties;
} }
@Schema(name = "PolygonProperties", description = "폴리곤 정보") @Schema(name = "PolygonProperties", description = "폴리곤 정보")
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public static class PolygonProperties { public static class PolygonProperties {
private Long geoUid;
private Double area; // 면적 private Double area; // 면적
private Integer beforeYear; // 기준년도 private Integer beforeYear; // 기준년도
private Double beforeConfidence; // 기준 신뢰도(확률) private Double beforeConfidence; // 기준 신뢰도(확률)

View File

@@ -34,12 +34,12 @@ public class ChangeDetectionService {
return changeDetectionCoreService.getChangeDetectionYearList(); return changeDetectionCoreService.getChangeDetectionYearList();
} }
public List<ChangeDetectionDto.PolygonGeometry> getChangeDetectionPolygonList( public ChangeDetectionDto.PolygonFeatureList getChangeDetectionPolygonList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return changeDetectionCoreService.getChangeDetectionPolygonList(analUid, mapSheetNum); return changeDetectionCoreService.getChangeDetectionPolygonList(analUid, mapSheetNum);
} }
public List<ChangeDetectionDto.PointGeometry> getChangeDetectionPointList( public List<ChangeDetectionDto.PointFeature> getChangeDetectionPointList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return changeDetectionCoreService.getChangeDetectionPointList(analUid, mapSheetNum); return changeDetectionCoreService.getChangeDetectionPointList(analUid, mapSheetNum);
} }

View File

@@ -31,10 +31,10 @@ public class ErrorLogApiController {
@RequestParam(required = false) LocalDate endDate, @RequestParam(required = false) LocalDate endDate,
@RequestParam int page, @RequestParam int page,
@RequestParam(defaultValue = "20") int size) { @RequestParam(defaultValue = "20") int size) {
ErrorLogDto.ErrorSearchReq searchReq = ErrorLogDto.ErrorSearchReq searchReq =
new ErrorLogDto.ErrorSearchReq( new ErrorLogDto.ErrorSearchReq(
logErrorLevel, eventType, startDate, endDate, page, size, "created_dttm,desc"); logErrorLevel, eventType, startDate, endDate, page, size, "created_dttm,desc");
Page<ErrorLogDto.Basic> result = errorLogService.findLogByError(searchReq); Page<ErrorLogDto.Basic> result = errorLogService.findLogByError(searchReq);
return ApiResponseDto.ok(result); return ApiResponseDto.ok(result);
} }
} }

View File

@@ -76,12 +76,12 @@ public class ChangeDetectionCoreService {
return changeDetectionRepository.getChangeDetectionYearList(); return changeDetectionRepository.getChangeDetectionYearList();
} }
public List<ChangeDetectionDto.PolygonGeometry> getChangeDetectionPolygonList( public ChangeDetectionDto.PolygonFeatureList getChangeDetectionPolygonList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return changeDetectionRepository.getChangeDetectionPolygonList(analUid, mapSheetNum); return changeDetectionRepository.getChangeDetectionPolygonList(analUid, mapSheetNum);
} }
public List<ChangeDetectionDto.PointGeometry> getChangeDetectionPointList( public List<ChangeDetectionDto.PointFeature> getChangeDetectionPointList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return changeDetectionRepository.getChangeDetectionPointList(analUid, mapSheetNum); return changeDetectionRepository.getChangeDetectionPointList(analUid, mapSheetNum);
} }

View File

@@ -15,10 +15,10 @@ public interface ChangeDetectionRepositoryCustom {
List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList(); List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList();
List<ChangeDetectionDto.PolygonGeometry> getChangeDetectionPolygonList( ChangeDetectionDto.PolygonFeatureList getChangeDetectionPolygonList(
Long analUid, String mapSheetNum); Long analUid, String mapSheetNum);
List<ChangeDetectionDto.PointGeometry> getChangeDetectionPointList( List<ChangeDetectionDto.PointFeature> getChangeDetectionPointList(
Long analUid, String mapSheetNum); Long analUid, String mapSheetNum);
List<ChangeDetectionDto.MapSheetList> getChangeDetectionMapSheetList(Long analUid); List<ChangeDetectionDto.MapSheetList> getChangeDetectionMapSheetList(Long analUid);

View File

@@ -10,6 +10,9 @@ import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalSttcEntity.map
import com.kamco.cd.kamcoback.changedetection.dto.ChangeDetectionDto; import com.kamco.cd.kamcoback.changedetection.dto.ChangeDetectionDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataEntity;
import com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
@@ -17,6 +20,9 @@ import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.geojson.GeoJsonReader;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport; import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
@@ -105,43 +111,79 @@ public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
} }
@Override @Override
public List<ChangeDetectionDto.PolygonGeometry> getChangeDetectionPolygonList( public ChangeDetectionDto.PolygonFeatureList getChangeDetectionPolygonList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return queryFactory
.select( List<Tuple> list =
Projections.constructor( queryFactory
ChangeDetectionDto.PolygonGeometry.class, .select(
Expressions.stringTemplate(
"ST_AsGeoJSON(ST_Transform({0}, 4326))", mapSheetAnalDataGeomEntity.geom),
mapSheetAnalDataGeomEntity.id, mapSheetAnalDataGeomEntity.id,
mapSheetAnalDataGeomEntity.geom, // polygon mapSheetAnalDataGeomEntity.area,
Projections.constructor( mapSheetAnalDataGeomEntity.compareYyyy,
ChangeDetectionDto.PolygonProperties.class, mapSheetAnalDataGeomEntity.classBeforeProb,
mapSheetAnalDataGeomEntity.area, mapSheetAnalDataGeomEntity.classBeforeCd.toUpperCase(),
mapSheetAnalDataGeomEntity.compareYyyy, mapSheetAnalDataGeomEntity.targetYyyy,
mapSheetAnalDataGeomEntity.classBeforeProb, mapSheetAnalDataGeomEntity.classAfterProb,
mapSheetAnalDataGeomEntity.classBeforeCd.toUpperCase(), mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase())
mapSheetAnalDataGeomEntity.targetYyyy, .from(QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity)
mapSheetAnalDataGeomEntity.classAfterProb, .where(
mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase()))) QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity.dataUid.in(
.from(mapSheetAnalDataGeomEntity) JPAExpressions.select(QMapSheetAnalDataEntity.mapSheetAnalDataEntity.id)
.where( .from(QMapSheetAnalDataEntity.mapSheetAnalDataEntity)
mapSheetAnalDataGeomEntity.dataUid.in( .where(QMapSheetAnalDataEntity.mapSheetAnalDataEntity.analUid.eq(analUid))),
JPAExpressions.select(mapSheetAnalDataEntity.id) QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity.mapSheetNum.eq(
.from(mapSheetAnalDataEntity) Long.valueOf(mapSheetNum)))
.where(mapSheetAnalDataEntity.analUid.eq(analUid))), .fetch();
mapSheetAnalDataGeomEntity.mapSheetNum.eq(Long.valueOf(mapSheetNum)))
.fetch(); GeoJsonReader reader = new GeoJsonReader();
List<ChangeDetectionDto.PolygonFeature> result =
list.stream()
.map(
tuple -> {
String geojson = tuple.get(0, String.class);
Geometry geom;
try {
geom = reader.read(geojson);
} catch (Exception ex) {
throw new RuntimeException("GeoJSON -> Geometry 변환 실패", ex);
}
ChangeDetectionDto.PolygonProperties properties =
new ChangeDetectionDto.PolygonProperties(
tuple.get(mapSheetAnalDataGeomEntity.id).longValue(),
tuple.get(mapSheetAnalDataGeomEntity.area).doubleValue(),
tuple.get(mapSheetAnalDataGeomEntity.compareYyyy).intValue(),
tuple.get(mapSheetAnalDataGeomEntity.classBeforeProb).doubleValue(),
tuple
.get(mapSheetAnalDataGeomEntity.classBeforeCd.toUpperCase())
.toString(),
tuple.get(mapSheetAnalDataGeomEntity.targetYyyy).intValue(),
tuple.get(mapSheetAnalDataGeomEntity.classAfterProb).doubleValue(),
tuple
.get(mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase())
.toString());
return new ChangeDetectionDto.PolygonFeature("Feature", geom, properties);
})
.collect(Collectors.toList());
ChangeDetectionDto.PolygonFeatureList polygonList = new ChangeDetectionDto.PolygonFeatureList();
polygonList.setType("FeatureCollection");
polygonList.setFeatures(result);
return polygonList;
} }
@Override @Override
public List<ChangeDetectionDto.PointGeometry> getChangeDetectionPointList( public List<ChangeDetectionDto.PointFeature> getChangeDetectionPointList(
Long analUid, String mapSheetNum) { Long analUid, String mapSheetNum) {
return queryFactory List<Tuple> list = queryFactory
.select( .select(
Projections.constructor( Expressions.stringTemplate(
ChangeDetectionDto.PointGeometry.class, "ST_AsGeoJSON(ST_Transform({0}, 4326))", mapSheetAnalDataGeomEntity.geomCenter),
mapSheetAnalDataGeomEntity.id, mapSheetAnalDataGeomEntity.id,
mapSheetAnalDataGeomEntity.geomCenter, // point mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase()
mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase())) )
.from(mapSheetAnalDataGeomEntity) .from(mapSheetAnalDataGeomEntity)
.where( .where(
mapSheetAnalDataGeomEntity.dataUid.in( mapSheetAnalDataGeomEntity.dataUid.in(
@@ -150,6 +192,25 @@ public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
.where(mapSheetAnalDataEntity.analUid.eq(analUid))), .where(mapSheetAnalDataEntity.analUid.eq(analUid))),
mapSheetAnalDataGeomEntity.mapSheetNum.eq(Long.valueOf(mapSheetNum))) mapSheetAnalDataGeomEntity.mapSheetNum.eq(Long.valueOf(mapSheetNum)))
.fetch(); .fetch();
GeoJsonReader reader = new GeoJsonReader();
return list.stream()
.map(
tuple -> {
String geojson = tuple.get(0, String.class);
Geometry geom;
try {
geom = reader.read(geojson);
} catch (Exception ex) {
throw new RuntimeException("GeoJSON -> Geometry 변환 실패", ex);
}
Long geoUid = tuple.get(mapSheetAnalDataGeomEntity.id).longValue();
String classCd = tuple.get(mapSheetAnalDataGeomEntity.classAfterCd.toUpperCase()).toString();
return new ChangeDetectionDto.PointFeature("Feature", geom, new ChangeDetectionDto.PointProperties(geoUid, classCd));
}
).collect(Collectors.toList());
} }
@Override @Override