변화탐지 API 커밋 cog,count,yearlist

This commit is contained in:
2025-11-27 18:01:15 +09:00
parent 9d32c85fd0
commit 675d2f2ed1
11 changed files with 343 additions and 16 deletions

View File

@@ -49,4 +49,25 @@ public class ChangeDetectionCoreService {
})
.collect(Collectors.toList());
}
public List<ChangeDetectionDto.CountDto> getChangeDetectionClassCount(Long id) {
return changeDetectionRepository.getChangeDetectionClassCount(id);
}
public ChangeDetectionDto.CogUrlDto getChangeDetectionCogUrl(ChangeDetectionDto.CogUrlReq req) {
ObjectMapper mapper = new ObjectMapper();
ChangeDetectionDto.CogUrlDto resultDto = changeDetectionRepository.getChangeDetectionCogUrl(req);
try {
JsonNode geomNode = mapper.readTree(resultDto.getBbox().toString());
resultDto.setBbox(geomNode);
} catch (Exception e) {
throw new RuntimeException("Failed to parse geom JSON", e);
}
return changeDetectionRepository.getChangeDetectionCogUrl(req);
}
public List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList() {
return changeDetectionRepository.getChangeDetectionYearList();
}
}

View File

@@ -0,0 +1,55 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import java.time.ZonedDateTime;
import java.util.UUID;
@Getter
@Setter
@Table(name = "imagery")
@Entity
public class ImageryEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "imagery_id_seq_gen")
@SequenceGenerator(name = "imagery_id_seq_gen",sequenceName = "imagery_id_seq",allocationSize = 1)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "uuid", columnDefinition = "uuid default gen_random_uuid()")
private UUID uuid;
@Column(name = "year")
private Integer year;
@Column(name = "scene_50k")
private String scene50k;
@Column(name = "scene_5k")
private String scene5k;
@Column(name = "scene_id_50k")
private Integer sceneId50k;
@Column(name = "scene_id_5k")
private Integer sceneId5k;
@ColumnDefault("now()")
@Column(name = "created_date", columnDefinition = "TIMESTAMP WITH TIME ZONE DEFAULT now()")
private ZonedDateTime createdDate;
@Column(name = "middle_path")
private String middlePath;
@Column(name = "cog_middle_path")
private String cogMiddlePath;
@Column(name = "filename")
private String filename;
@Column(name = "cog_filename")
private String cogFilename;
}

View File

@@ -0,0 +1,33 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.locationtech.jts.geom.Geometry;
@Getter
@Setter
@Table(name = "tb_map_inkx_50k")
@Entity
public class MapInkx50kEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_50k_fid_seq_gen")
@SequenceGenerator(
name = "tb_map_inkx_50k_fid_seq_gen",
sequenceName = "tb_map_inkx_50k_fid_seq",
allocationSize = 1)
private Integer fid;
@Column(name = "mapidcd_no")
private String mapidcdNo;
@Column(name = "mapid_nm")
private String mapidNm;
@Column(name = "mapid_no")
private String mapidNo;
@Column(name = "geom")
private Geometry geom;
}

View File

@@ -0,0 +1,32 @@
package com.kamco.cd.kamcoback.postgres.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.locationtech.jts.geom.Geometry;
@Getter
@Setter
@Table(name = "tb_map_inkx_5k")
@Entity
public class MapInkx5kEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tb_map_inkx_5k_fid_seq_gen")
@SequenceGenerator(
name = "tb_map_inkx_5k_fid_seq_gen",
sequenceName = "tb_map_inkx_5k_fid_seq",
allocationSize = 1)
private Integer fid;
@Column(name = "mapidcd_no")
private String mapidcdNo;
@Column(name = "mapid_nm")
private String mapidNm;
@Column(name = "geom")
private Geometry geom;
@Column(name = "fid_k50")
private Long fidK50;
}

View File

@@ -91,4 +91,7 @@ public class MapSheetAnalEntity {
@Column(name = "detecting_cnt")
private Long detectingCnt;
@Column(name = "base_map_sheet_num")
private String baseMapSheetNum;
}

View File

@@ -47,6 +47,12 @@ public class MapSheetAnalSttcEntity {
@Column(name = "data_uid", nullable = false)
private Long dataUid;
@Column(name = "class_before_cd")
private String classBeforeCd;
@Column(name = "class_after_cd")
private String classAfterCd;
public InferenceResultDto.Dashboard toDto() {
return new InferenceResultDto.Dashboard(
id.getCompareYyyy(),

View File

@@ -1,5 +1,8 @@
package com.kamco.cd.kamcoback.postgres.repository.changedetection;
import com.kamco.cd.kamcoback.changedetection.dto.ChangeDetectionDto;
import com.querydsl.core.Tuple;
import java.util.List;
public interface ChangeDetectionRepositoryCustom {
@@ -7,4 +10,10 @@ public interface ChangeDetectionRepositoryCustom {
String getPolygonToPoint();
List<String> findPolygonJson();
List<ChangeDetectionDto.CountDto> getChangeDetectionClassCount(Long id);
ChangeDetectionDto.CogUrlDto getChangeDetectionCogUrl(ChangeDetectionDto.CogUrlReq req);
List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList();
}

View File

@@ -1,13 +1,28 @@
package com.kamco.cd.kamcoback.postgres.repository.changedetection;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.changedetection.dto.ChangeDetectionDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataGeomEntity;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import java.util.List;
import java.util.Objects;
import static com.kamco.cd.kamcoback.postgres.entity.QImageryEntity.imageryEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapInkx5kEntity.mapInkx5kEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataEntity.mapSheetAnalDataEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalDataGeomEntity.mapSheetAnalDataGeomEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalEntity.mapSheetAnalEntity;
import static com.kamco.cd.kamcoback.postgres.entity.QMapSheetAnalSttcEntity.mapSheetAnalSttcEntity;
public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
implements ChangeDetectionRepositoryCustom {
@@ -34,4 +49,83 @@ public class ChangeDetectionRepositoryImpl extends QuerydslRepositorySupport
.orderBy(mapSheetAnalDataGeomEntity.id.desc())
.fetch();
}
@Override
public List<ChangeDetectionDto.CountDto> getChangeDetectionClassCount(Long id) {
return queryFactory
.select(Projections.constructor(
ChangeDetectionDto.CountDto.class,
mapSheetAnalSttcEntity.classAfterCd.toUpperCase(),
mapSheetAnalSttcEntity.id.classAfterName,
mapSheetAnalSttcEntity.classAfterCnt.sum()
))
.from(mapSheetAnalEntity)
.innerJoin(mapSheetAnalDataEntity)
.on(mapSheetAnalDataEntity.analUid.eq(mapSheetAnalEntity.id))
.innerJoin(mapSheetAnalSttcEntity)
.on(mapSheetAnalSttcEntity.dataUid.eq(mapSheetAnalDataEntity.id))
.where(mapSheetAnalEntity.id.eq(id))
.groupBy(mapSheetAnalSttcEntity.classAfterCd, mapSheetAnalSttcEntity.id.classAfterName)
.fetch();
}
@Override
public ChangeDetectionDto.CogUrlDto getChangeDetectionCogUrl(ChangeDetectionDto.CogUrlReq req) {
Tuple result = queryFactory
.select(
makeCogUrl(req.getBeforeYear()).max().as("beforeCogUrl"),
makeCogUrl(req.getAfterYear()).max().as("afterCogUrl"),
Expressions.stringTemplate("ST_AsGeoJSON({0})", mapInkx5kEntity.geom).as("bbox")
)
.from(imageryEntity)
.innerJoin(mapInkx5kEntity)
.on(imageryEntity.scene5k.eq(mapInkx5kEntity.mapidcdNo))
.where(
imageryEntity.year.eq(req.getBeforeYear()).or(imageryEntity.year.eq(req.getAfterYear())),
imageryEntity.scene5k.eq(req.getMapSheetNum())
)
.groupBy(mapInkx5kEntity.geom)
.fetchOne();
//Polygon -> JsonNode 로 변환
JsonNode geometryJson = changeGeometryJson(String.valueOf(Objects.requireNonNull(result).get(2, StringExpression.class)));
return new ChangeDetectionDto.CogUrlDto(result.get(0, String.class), result.get(1, String.class), geometryJson);
}
@Override
public List<ChangeDetectionDto.AnalYearList> getChangeDetectionYearList() {
return queryFactory
.select(
Projections.constructor(
ChangeDetectionDto.AnalYearList.class,
mapSheetAnalEntity.id,
mapSheetAnalEntity.analTitle,
mapSheetAnalEntity.compareYyyy.as("beforeYear"),
mapSheetAnalEntity.targetYyyy.as("afterYear"),
mapSheetAnalEntity.baseMapSheetNum
)
)
.from(mapSheetAnalEntity)
.orderBy(mapSheetAnalEntity.id.asc())
.fetch()
;
}
private StringExpression makeCogUrl(Integer year) {
return new CaseBuilder()
.when(imageryEntity.year.eq(year))
.then(Expressions.stringTemplate("{0} || {1}",imageryEntity.cogMiddlePath, imageryEntity.cogFilename))
.otherwise("")
;
}
private JsonNode changeGeometryJson(String geometry){
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readTree(geometry);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}