Compare commits
12 Commits
f9caf1fa73
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 4040ac950a | |||
| 20432c8f8a | |||
| 988fb49036 | |||
| 2772b41dcf | |||
| c731ad607d | |||
| beedc4b8a6 | |||
| 3fbac59788 | |||
| 600bdce4ac | |||
| 8a9a150638 | |||
| 6d6f22b9da | |||
| 08a3aeab20 | |||
| d3c4d98254 |
@@ -6,25 +6,22 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DetectionClassification {
|
||||
BUILDING("building", "건물", 10),
|
||||
CONTAINER("container", "컨테이너", 20),
|
||||
FIELD("field", "경작지", 30),
|
||||
FOREST("forest", "숲", 40),
|
||||
GRASS("grass", "초지", 50),
|
||||
GREENHOUSE("greenhouse", "비닐하우스", 60),
|
||||
LAND("land", "일반토지", 70),
|
||||
ORCHARD("orchard", "과수원", 80),
|
||||
ROAD("road", "도로", 90),
|
||||
STONE("stone", "모래/자갈", 100),
|
||||
TANK("tank", "물탱크", 110),
|
||||
TUMULUS("tumulus", "토분(무덤)", 120),
|
||||
WASTE("waste", "폐기물", 130),
|
||||
WATER("water", "물", 140),
|
||||
CONSTRUCTION("construction", "건설", 150),
|
||||
NDC("NDC", "미분류", 160),
|
||||
RICE("rice", "논", 170),
|
||||
WOOD("wood", "산림", 180),
|
||||
ETC("ETC", "기타", 200); // For 'etc' (miscellaneous/other)
|
||||
ROAD("road", "도로", 10),
|
||||
BUILDING("building", "건물", 20),
|
||||
GREENHOUSE("greenhouse", "비닐하우스", 30),
|
||||
FIELD("field", "논/밭", 40),
|
||||
ORCHARD("orchard", "과수원", 50),
|
||||
GRASS("grass", "초지", 60),
|
||||
FOREST("forest", "숲", 70),
|
||||
WATER("water", "물", 80),
|
||||
STONE("stone", "모래/자갈", 90),
|
||||
WASTE("waste", "적치물", 100),
|
||||
CONTAINER("container", "컨테이너", 110),
|
||||
LAND("land", "일반토지", 120),
|
||||
SOLAR("solar", "태양광", 130),
|
||||
TANK("tank", "물탱크", 140),
|
||||
NDC("NDC", "미분류", 150),
|
||||
ETC("ETC", "기타", 160);
|
||||
|
||||
private final String id;
|
||||
private final String desc;
|
||||
|
||||
@@ -420,14 +420,18 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto
|
||||
|
||||
if (searchGeoReq.getTargetClass() != null && !searchGeoReq.getTargetClass().isBlank()) {
|
||||
where.and(
|
||||
mapSheetAnalDataInferenceGeomEntity.classAfterCd.eq(
|
||||
searchGeoReq.getTargetClass().toLowerCase()));
|
||||
mapSheetAnalDataInferenceGeomEntity
|
||||
.classAfterCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getTargetClass().toLowerCase()));
|
||||
}
|
||||
|
||||
if (searchGeoReq.getCompareClass() != null && !searchGeoReq.getCompareClass().isBlank()) {
|
||||
where.and(
|
||||
mapSheetAnalDataInferenceGeomEntity.classBeforeCd.eq(
|
||||
searchGeoReq.getCompareClass().toLowerCase()));
|
||||
mapSheetAnalDataInferenceGeomEntity
|
||||
.classBeforeCd
|
||||
.toLowerCase()
|
||||
.eq(searchGeoReq.getCompareClass().toLowerCase()));
|
||||
}
|
||||
|
||||
if (searchGeoReq.getMapSheetNum() != null) {
|
||||
|
||||
@@ -98,7 +98,7 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
|
||||
.from(auditLogEntity)
|
||||
.leftJoin(menuEntity)
|
||||
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
|
||||
.where(menuNameEquals(searchValue))
|
||||
.where(auditLogEntity.menuUid.ne("SYSTEM"), menuNameEquals(searchValue))
|
||||
.groupBy(auditLogEntity.menuUid)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
@@ -139,7 +139,7 @@ public class AuditLogRepositoryImpl extends QuerydslRepositorySupport
|
||||
.from(auditLogEntity)
|
||||
.leftJoin(memberEntity)
|
||||
.on(auditLogEntity.userUid.eq(memberEntity.id))
|
||||
.where(loginIdOrUsernameContains(searchValue))
|
||||
.where(auditLogEntity.userUid.isNotNull(), loginIdOrUsernameContains(searchValue))
|
||||
.groupBy(auditLogEntity.userUid, memberEntity.employeeNo, memberEntity.name)
|
||||
.offset(pageable.getOffset())
|
||||
.limit(pageable.getPageSize())
|
||||
|
||||
@@ -13,14 +13,16 @@ public class MapSheetMngFileJobController {
|
||||
private final MapSheetMngFileJobService mapSheetMngFileJobService;
|
||||
|
||||
// 현재 상태 확인용 Getter
|
||||
@Getter private boolean isSchedulerEnabled = false;
|
||||
@Getter private boolean isSchedulerEnabled = true;
|
||||
@Getter private boolean isFileSyncSchedulerEnabled = false;
|
||||
@Getter private int mngSyncPageSize = 20;
|
||||
|
||||
// 파일싱크 진행여부 확인하기
|
||||
@Scheduled(fixedDelay = 1000 * 10)
|
||||
public void checkMngFileSync() {
|
||||
if (!isSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
Integer mng = 0;
|
||||
// isFileSyncSchedulerEnabled = false;
|
||||
@@ -28,23 +30,19 @@ public class MapSheetMngFileJobController {
|
||||
mng = mapSheetMngFileJobService.checkMngFileSync();
|
||||
this.isFileSyncSchedulerEnabled = true;
|
||||
System.out.println(
|
||||
"MngFileSyncJob ON --> mngYyyy : "
|
||||
+ mng
|
||||
+ ", currentTime : "
|
||||
+ System.currentTimeMillis());
|
||||
"MngFileSyncJob --> mngYyyy : " + mng + ", currentTime : " + System.currentTimeMillis());
|
||||
} else {
|
||||
this.isFileSyncSchedulerEnabled = false;
|
||||
System.out.println(
|
||||
"MngFileSyncJob OFF --> mngYyyy : "
|
||||
+ mng
|
||||
+ ", currentTime : "
|
||||
+ System.currentTimeMillis());
|
||||
"MngFileSyncJob --> mngYyyy : " + mng + ", currentTime : " + System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 10)
|
||||
public void mngFileSyncJob00() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 00 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(0, mngSyncPageSize);
|
||||
@@ -52,7 +50,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob01() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 01 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(1, mngSyncPageSize);
|
||||
@@ -60,7 +60,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob02() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 02 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(2, mngSyncPageSize);
|
||||
@@ -68,7 +70,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob03() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 03 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(3, mngSyncPageSize);
|
||||
@@ -76,7 +80,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob04() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 04 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(4, mngSyncPageSize);
|
||||
@@ -84,7 +90,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob05() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 05 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(5, mngSyncPageSize);
|
||||
@@ -92,7 +100,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob06() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 06 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(6, mngSyncPageSize);
|
||||
@@ -100,7 +110,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob07() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 07 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(7, mngSyncPageSize);
|
||||
@@ -108,7 +120,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob08() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 08 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(8, mngSyncPageSize);
|
||||
@@ -116,7 +130,9 @@ public class MapSheetMngFileJobController {
|
||||
|
||||
@Scheduled(fixedDelay = 1000 * 5)
|
||||
public void mngFileSyncJob09() {
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) return;
|
||||
if (!isSchedulerEnabled || !isFileSyncSchedulerEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("mngFileSyncJob 09 Processing currentTime : " + System.currentTimeMillis());
|
||||
mapSheetMngFileJobService.checkMapSheetFileProcess(9, mngSyncPageSize);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
## 📌 학습데이터 라벨링 geojson 생성
|
||||
|
||||
### 🧩 사용하는 테이블 목록
|
||||
|
||||
- inference_results_testing : AI 수행 이후 변화탐지된 polygon insert 됨
|
||||
- tb_map_sheet_anal_inference : 추론 실행 완료 후, 추론 마스터 값 insert
|
||||
- anal_state : 학습데이터 제작 상태 -> (enum) `LabelMngState`
|
||||
- 💡 tb_map_sheet_anal_data_inference_geom 💡 : 추론 실행 완료 후, testing 값 insert
|
||||
- tb_labeling_inspector : 라벨링 할당 시 선택한 검수자 insert
|
||||
- 라벨링 할당 시 해당 회차별 검수자를 insert
|
||||
- 매일 0시 스케줄링, 어제 라벨링 완료한 데이터 기준 검수 할당 진행
|
||||
- 💡 tb_labeling_assignment 💡 : 라벨링 할당 테이블 (polygon 수만큼)
|
||||
- worker_uid : 라벨러 사번
|
||||
- inspector_uid : 검수자 사번
|
||||
- work_state : 라벨 진행 상태 -> (enum) `LabelState`
|
||||
- inspect_state : 검수 진행 상태 -> (enum) `InspectState`
|
||||
- work_stat_dttm : 라벨 상태 변경일시
|
||||
- inspect_stat_dttm : 검수 상태 변경일시
|
||||
- 💡 tb_map_sheet_learn_data_geom 💡 : 라벨링 툴에서 그린 polygon insert/update
|
||||
- file_create_yn : geojson 파일 생성 후 true 로 업데이트
|
||||
|
||||
**💡표기된 테이블은 geo_uid (Long) 값으로 연결됨**
|
||||
|
||||
### 🧩 스케줄링 로직
|
||||
|
||||
✅ 파일 위치 : TrainingDataReviewJobService.java
|
||||
|
||||
#### 1. 라벨링 완료 건 검수 할당
|
||||
|
||||
- Method : assignReviewerYesterdayLabelComplete
|
||||
- 매일 00시 00분 수행 (시간 변경 가능)
|
||||
- 라벨링 상태 `work_state = DONE`
|
||||
- 라벨링 상태 변경일시(work_stat_dttm) 기준 어제인 건 조회하여 할당
|
||||
- 실패 시, 수동 호출 API : `/api/training-data/review/run-schedule`
|
||||
|
||||
#### 2. 학습데이터 geojson 생성
|
||||
|
||||
- Method : exportGeojsonLabelingGeom
|
||||
- 매일 02시 00분 수행 (시간 변경 가능)
|
||||
- 학습데이터 제작 상태가 `ING`인 회차
|
||||
- 어제까지 검수 상태 업데이트 된 polygon (`inspect_stat_dttm`)
|
||||
- geojson 제작 대상은 누적으로 조회함
|
||||
- `inspect_state = 'COMPLETE'`
|
||||
- `inspect_stat_dttm < 오늘 이전 모두`
|
||||
- 파일 생성 후 polygon별 `file_create_yn = true` 로 업데이트
|
||||
- 회차에 할당된 polygon 총 개수(제외상태 빼고) = `file_create_yn = true` 인 개수가 맞을 때까지 스케줄링 진행
|
||||
- 실패 시, 수동 호출 API : `/api/training-data/review/run-label-geojson`
|
||||
- 파일 생성 위치: `/kamco-nfs/model_output/labeling/`
|
||||
- ️📚 생성 규칙
|
||||
|
||||
```
|
||||
/kamco-nfs/model_output/labeling/
|
||||
└─ {RESULT_UID}
|
||||
└─{RESULT_UID 8자리}_{비교년도}_{기준년도}_{도엽번호}_D15.geojson
|
||||
```
|
||||
|
||||
### 🧩 사용 쿼리
|
||||
|
||||
- 📄 TRAINING_DATA_GEOJSON_QUERY.sql 참고
|
||||
|
||||
### 🧩 라벨링 툴 접속 가능한 계정
|
||||
|
||||
`* password : qwe123!@#`
|
||||
|
||||
1. 라벨러
|
||||
|
||||
- 010222297501
|
||||
- 98765432
|
||||
- 20202020
|
||||
- 123456
|
||||
- 01022223333
|
||||
|
||||
2. 검수자
|
||||
|
||||
- 01022225555
|
||||
- 125511
|
||||
- K20251212001
|
||||
@@ -0,0 +1,85 @@
|
||||
--1. 학습데이터 진행 중 회차 조회
|
||||
select lae1_0.anal_uid,
|
||||
msle1_0.uid,
|
||||
sum(case
|
||||
when (lae1_0.inspect_state = 'UNCONFIRM'
|
||||
or lae1_0.inspect_state = 'COMPLETE'
|
||||
or lae1_0.inspect_state is null)
|
||||
then 1
|
||||
else 0
|
||||
end), --allCnt
|
||||
sum(case
|
||||
when (lae1_0.inspect_state = 'COMPLETE')
|
||||
then 1
|
||||
else 0
|
||||
end), --completeCnt
|
||||
sum(case
|
||||
when (msldge1_0.file_create_yn = true)
|
||||
then 1
|
||||
else 0
|
||||
end) --fileCnt
|
||||
from tb_labeling_assignment lae1_0
|
||||
join
|
||||
tb_map_sheet_anal_inference msaie1_0
|
||||
on lae1_0.anal_uid = msaie1_0.anal_uid
|
||||
and msaie1_0.anal_state = 'ING' --학습데이터 제작 진행중인 회차
|
||||
left join
|
||||
tb_map_sheet_learn msle1_0
|
||||
on msaie1_0.learn_id = msle1_0.id
|
||||
left join
|
||||
tb_map_sheet_learn_data_geom msldge1_0
|
||||
on lae1_0.inference_geom_uid = msldge1_0.geo_uid --라벨링 할당 테이블과 geo_uid 가 같은 값으로 매핑되어 있음
|
||||
group by lae1_0.anal_uid,
|
||||
msle1_0.uid
|
||||
having sum(case
|
||||
when (lae1_0.inspect_state = 'COMPLETE')
|
||||
then 1
|
||||
else 0
|
||||
end) > 0 --검수할당 COMPLETE 상태가 있는 회차만 검색
|
||||
;
|
||||
|
||||
--2. 해당 회차 + 어제까지 검수 완료된 도엽 조회
|
||||
select msaie1_0.compare_yyyy,
|
||||
msaie1_0.target_yyyy,
|
||||
lae1_0.assign_group_id
|
||||
from tb_labeling_assignment lae1_0
|
||||
join
|
||||
tb_map_sheet_anal_inference msaie1_0
|
||||
on lae1_0.anal_uid = msaie1_0.anal_uid
|
||||
where lae1_0.anal_uid = 52 --해당 회차
|
||||
and lae1_0.inspect_state = 'COMPLETE' --검수 완료 상태
|
||||
and lae1_0.inspect_stat_dttm < '2026-01-23T00:00+09:00' --검수상태변경일 오늘 이전 모두
|
||||
group by msaie1_0.compare_yyyy,
|
||||
msaie1_0.target_yyyy,
|
||||
lae1_0.assign_group_id
|
||||
;
|
||||
|
||||
-- 3. 회차 + 도엽에 검수 완료된 polygon 조회
|
||||
select msldge1_0.geo_uid,
|
||||
cast('Feature' as varchar),
|
||||
st_asgeojson(msldge1_0.geom),
|
||||
case
|
||||
when (msldge1_0.class_after_cd in ('building', 'container'))
|
||||
then cast('M1' as varchar)
|
||||
when (msldge1_0.class_after_cd = 'waste')
|
||||
then cast('M2' as varchar)
|
||||
else 'M3'
|
||||
end,
|
||||
msldge1_0.class_before_cd,
|
||||
msldge1_0.class_after_cd
|
||||
from tb_labeling_assignment lae1_0
|
||||
left join
|
||||
tb_map_sheet_learn_data_geom msldge1_0 --라벨링 그린 polygon 저장 테이블
|
||||
on lae1_0.inference_geom_uid = msldge1_0.geo_uid
|
||||
where lae1_0.anal_uid = 52
|
||||
and lae1_0.assign_group_id = '34602060'
|
||||
and lae1_0.inspect_state = 'COMPLETE'
|
||||
and lae1_0.inspect_stat_dttm < '2026-01-23T00:00+09:00'
|
||||
;
|
||||
|
||||
--4. 파일 생성한 learn_data_geom 에 file_create_yn = true 로 업데이트
|
||||
update tb_map_sheet_learn_data_geom msldge1_0
|
||||
set file_create_yn= true,
|
||||
updated_dttm='2026-01-23T19:27:28.623677700+09:00'
|
||||
where msldge1_0.geo_uid = 390913
|
||||
;
|
||||
Reference in New Issue
Block a user