13 KiB
13 KiB
0_old vs 현재 프로젝트 혼선 지점 분석 (Critical for Coders)
작성일: 2026-07-10
목적: 0_old 코드 참고 시 발생할 수 있는 통합 오류 사전 차단
1. 데이터 구조 & 저장소 경로 차이
1.1 저장소 경로 구조
| 항목 | 0_old | 현재 프로젝트 |
|---|---|---|
| 기본 경로 | storage/projects/{projectId}/ |
storage/{company_slug}/{user_slug}/{projectId}/ |
| 원본 입력 | input/ (명확하지 않음) |
B03_FileInput/input/ |
| 처리 결과 | processed/ (모든 것을 한곳에) |
B04_wf1_Surface/processed/ (분산) |
| 지표면 모델 | processed/ 내 JSON |
B04_wf1_Surface/models/ |
| 경로 데이터 | route_design/ |
B05_wf2_Route/route/ |
| 종횡단면 | sections/ |
B06_wf3_ProfileCross/ |
코더 주의:
- 0_old의 경로를 그대로 현재 코드에 복사하면 파일을 찾을 수 없음
- 항상
config_system.py의PROJECT_STORAGE_STAGE_DIRS확인 - 경로 변환은
common_util_storage.py의resolve_stored_project_path()사용
예시 오류:
# ❌ 0_old 방식
path = f"storage/projects/{projectId}/processed/tin.json"
# ✅ 현재 방식
from common_util.common_util_storage import resolve_stored_project_path
stored_path = await get_project_storage_relative_path(connection, projectId)
project_root = Path(resolve_stored_project_path(stored_path))
path = project_root / "B04_wf1_Surface" / "models" / "tin.json"
2. API 엔드포인트 & 요청/응답 구조
2.1 0_old API 엔드포인트
| 메서드 | 경로 | 목적 |
|---|---|---|
| GET | /api/projects/{projectId}/analysis |
분석 결과 조회 |
| GET | /api/projects/{projectId}/las-points |
LAS 포인트 샘플 조회 |
| GET | /api/projects/{projectId}/all-points |
모든 포인트 조회 |
| GET | /api/projects/{projectId}/ground-points |
지면 포인트만 조회 |
| POST | /api/projects/{projectId}/analyze-ground |
분석 실행 (동기) |
| GET | /api/projects/{projectId}/terrain-models |
지표면 모델 목록 |
| POST | /api/projects/{projectId}/route/solve |
경로 계산 |
| POST | /api/projects/{projectId}/sections/generate |
종횡단면 생성 |
2.2 현재 프로젝트 API 엔드포인트
| 메서드 | 경로 | 목적 |
|---|---|---|
| POST | /api/projects/{projectId}/surface/analyze |
분석 실행 (비동기, 상태 저장) |
| GET | /api/projects/{projectId}/surface/status |
분석 상태 및 진행률 조회 |
| GET | /api/projects/{projectId}/surface/models |
지표면 모델 목록 |
| GET | /api/projects/{projectId}/surface/point-cloud |
포인트 샘플 조회 |
| GET | /api/projects/{projectId}/surface/ground-stats |
지면 필터 통계 |
| POST | /api/projects/{projectId}/files |
파일 업로드 (다중) |
| POST | /api/projects/{projectId}/upload-sessions |
청크 업로드 세션 시작 |
| POST | /api/projects/{projectId}/chunks |
청크 업로드 |
| POST | /api/projects/{projectId}/finalize |
업로드 완료 |
코더 주의:
- 0_old의
/api/projects/{projectId}/analyze-ground는 현재에 없음 - 현재는
/api/projects/{projectId}/surface/analyze+/api/projects/{projectId}/surface/status조합 - 0_old 코드 마이그레이션 시 비동기 처리 방식 변경 필수
3. 프론트엔드 기술 스택 차이
3.1 라이브러리 버전
| 라이브러리 | 0_old | 현재 프로젝트 | 비고 |
|---|---|---|---|
| React | 19.2.7 | 없음 | critical diff |
| React-DOM | 19.2.7 | 없음 | critical diff |
| lucide-react | 1.23.0 | 없음 | 아이콘 라이브러리 |
| THREE.js | 0.185.0 | 0.185.0 | ✅ 동일 |
| MapLibre-GL | 5.24.0 | 없음 | 지도 렌더러 |
| TypeScript | 6.0.3 | 5.x (확인 필요) | 버전 차이 가능성 |
코더 주의:
- 0_old의 모든
.tsx컴포넌트는 React 훅 기반 - 현재 프로젝트는 바닐라 TypeScript + DOM 조작
- 0_old 컴포넌트를 현재 프로젝트에 복사하면 즉시 오류 (React 불가)
3.2 필수 변환 규칙 (0_old → 현재)
React 훅 → 클로저 + 렌더 함수
// ❌ 0_old (React 훅)
function PointCloudViewer({ projectId }: { projectId: string }) {
const [scale, setScale] = useState<number>(1.0);
useEffect(() => { /* initialization */ }, [projectId]);
return <div>...</div>;
}
// ✅ 현재 (바닐라 TS)
function createPointCloudViewer(projectId: string): HTMLElement {
let scale = 1.0;
const container = document.createElement('div');
const initialize = async () => { /* initialization */ };
initialize();
return container;
}
JSX → createElement (또는 템플릿 리터럴)
// ❌ 0_old (JSX)
<button onClick={() => handleClick()}>Click me</button>
// ✅ 현재 (DOM 직접 생성)
const button = document.createElement('button');
button.textContent = 'Click me';
button.addEventListener('click', handleClick);
lucide-react 아이콘 → 인라인 SVG / 유니코드
// ❌ 0_old (lucide-react)
import { FileUp } from 'lucide-react';
<FileUp size={24} />
// ✅ 현재 (유니코드 또는 SVG)
const icon = document.createElement('span');
icon.textContent = '📤'; // 또는 인라인 SVG
4. 분석 엔진 & 백엔드 알고리즘
4.1 0_old 분석 프로세스
0_old/backend/app/analyzer.py:
analyze_project()— 동기식 전체 분석 실행- LAS 로드 및 메타데이터 추출
- 포인트 클라우드 필터 적용 (CSF, PMF, RANSAC, grid_min_z)
- 지표면 모델 생성 (TIN, DTM, NURBS, implicit, meshfree 등)
- 결과를
storage/projects/{projectId}/processed/analysis.json에 저장
결과 저장 형식:
{
"timestamp": "2025-07-10T...",
"project_files": { /* file metadata */ },
"point_cloud_summary": { "total": 1000000, ... },
"ground_filter_results": { "csf": { ... }, "pmf": { ... }, ... },
"terrain_models": {
"tin": { "model_file": "...", "contours": [...] },
"dtm": { ... }
}
}
4.2 현재 프로젝트 분석 프로세스
B04_wf1_Surface/B04_wf1_Surface_Engine.py:
run_surface_analysis()— 동기식이지만, 라우터에서asyncio.to_thread()로 실행- 결과를 여러 개의 DB 테이블에 저장:
processed_point_clouds테이블surface_models테이블terrain_layers테이블
- 파일 경로도 함께 DB에 저장 (
model_file_path,layer_file_path등)
코더 주의:
- 0_old는 JSON 파일 중심, 현재는 DB + 파일 경로 이원화
- 분석 결과 조회 시:
- 0_old:
storage/projects/{projectId}/processed/analysis.json직접 읽기 - 현재:
surface_models테이블 쿼리 + 필요한 파일을 경로로 로드
- 0_old:
5. 프론트엔드 상태 관리 & LocalStorage
5.1 0_old 상태 관리
main.tsx에서 useState 사용:
projectId— 현재 프로젝트 IDstage— 현재 워크플로우 단계analysisResult— 분석 결과 캐시selectedRoute— 선택된 경로- 등등
localStorage 미사용 (또는 매우 제한적)
5.2 현재 프로젝트 상태 관리
config_frontend.ts:
const CURRENT_PROJECT_ID_KEY = "frd_current_project_id";
localStorage 의존성:
- 프로젝트 ID는 반드시 localStorage에 저장
- 페이지 네비게이션 시 projectId 복구
- 청크 업로드 세션 정보도 localStorage 유지
코더 주의:
- 0_old 코드를 현재 프로젝트에 옮길 때, localStorage 복구 로직 추가 필수
- 특히 B04, B05, B06 페이지는 모두
CURRENT_PROJECT_ID_KEY의존
6. 3D 렌더링 (THREE.js) — 유사성
6.1 공통점
0_old와 현재 모두 THREE.js 0.185.0 사용:
PointCloudViewer.tsx→ 포인트 클라우드 렌더링TerrainModelViewer.tsx→ 지표면 모델 렌더링- OrbitControls 사용 (카메라 조작)
코더에게 좋은 소식:
- THREE.js 부분은 상대적으로 간단한 변환 가능
- 렌더 루프, 조명, 카메라 로직은 큰 변경 불필요
- DOM 생성 부분만 수정하면 대부분 재사용 가능
예시:
// ❌ 0_old (JSX)
<Canvas camera={{ position: [100, 100, 100] }}>
<mesh>...</mesh>
</Canvas>
// ✅ 현재 (THREE.js 직접)
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 10000);
camera.position.set(100, 100, 100);
const renderer = new THREE.WebGLRenderer();
renderer.render(scene, camera);
7. 필터 알고리즘 (Python) — 재사용 가능
7.1 0_old 필터 유틸리티
0_old/utils/ 디렉토리:
filter_csf.py— Cloth Simulation Filterfilter_pmf.py— Progressive Morphological Filterfilter_ransac.py— RANSAC-기반 필터filter_grid_min_z.py— Grid Min-Z 필터
현재 프로젝트에서 이 필터들을 사용하는가?
- ✅ 네,
B04_wf1_Surface_Engine.py에서 참고 - 동일한 필터 알고리즘 재구현 가능
코더 주의:
- 필터 알고리즘은 그대로 복사 가능 (Python 코드)
- 하지만 경로, DB 저장 방식은 변경 필수
8. 라우팅 & 네비게이션 차이
8.1 0_old 라우팅
main.tsx에서 React Router 미사용, 수동 state 관리:
if (stage === "TERRAIN_ANALYSIS") {
return <TerrainAnalysisStage />;
} else if (stage === "ROUTE_DESIGN") {
return <RouteDesignStage />;
}
// ...
8.2 현재 프로젝트 라우팅
A00_Common/A00_Common_UI_Navigator.ts에서 수동 SPA 라우팅:
function navigateTo(route: string): void {
window.location.hash = route;
// ...
}
코더 주의:
- 0_old 코드를 현재에 적용할 때,
navigateTo()사용 필수 - localStorage 저장 + 네비게이션 순서 엄격 준수 (§2.2.2 참고)
9. 체크리스트 for Coders
0_old 코드를 현재 프로젝트에 통합할 때 반드시 확인:
파일 경로
storage/projects/...→storage/{company}/{user}/{projectId}/B0N_...변환- 하드코딩된 경로 제거
resolve_stored_project_path()및PROJECT_STORAGE_STAGE_DIRS사용
API 호출
- 엔드포인트 변경 (
/analyze-ground→/surface/analyze) - 비동기 처리 추가 (폴링 로직)
- 요청/응답 포맷 확인
프론트엔드 컴포넌트
- React 훅 → 클로저 + 렌더 함수 변환
- JSX →
createElement또는 템플릿 리터럴 변환 - lucide-react 아이콘 → 유니코드/인라인 SVG 변환
- localStorage 의존성 추가 (
CURRENT_PROJECT_ID_KEY)
상태 관리
useState호출 제거- localStorage에 상태 저장 확인
- 페이지 리로드 후 복구 로직 확인
THREE.js 렌더링
- 캔버스 생성 부분 확인
- 렌더 루프 설정 확인
- 이벤트 리스너(resize, click 등) 추가
DB 저장
- JSON 파일 저장에서 DB 테이블 저장으로 변경
- 파일 경로를 DB에 함께 저장
- 트랜잭션 처리 확인
10. 예시: 0_old PointCloudViewer 변환
0_old (React + JSX)
// 0_old/frontend/src/PointCloudViewer.tsx (간략)
export function PointCloudViewer({ projectId }: { projectId: string }) {
const [scale, setScale] = useState(1.0);
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
const renderer = new THREE.WebGLRenderer({ canvas });
// 렌더링 설정
}, [projectId]);
return <canvas ref={canvasRef} />;
}
현재 프로젝트 (바닐라 TS)
// B04_wf1_Surface/B04_wf1_Surface_UI_PointCloud.ts (신규)
export function createPointCloudViewer(projectId: string): HTMLElement {
let scale = 1.0;
const canvas = document.createElement('canvas');
const initialize = async () => {
const renderer = new THREE.WebGLRenderer({ canvas });
// 렌더링 설정
const response = await fetch(`/api/projects/${projectId}/surface/point-cloud`);
const data = await response.json();
// 포인트 클라우드 렌더
};
initialize();
return canvas;
}
11. 결론
| 영역 | 재사용 난이도 | 주의사항 |
|---|---|---|
| 경로 구조 | 높음 | 전체 매핑 필요 |
| API 엔드포인트 | 높음 | 비동기 처리 방식 변경 |
| 프론트엔드 컴포넌트 | 높음 | React → TS 변환 필수 |
| 필터 알고리즘 | 낮음 | 경로 변수만 수정 |
| THREE.js 렌더링 | 낮음 | JSX → DOM 생성만 수정 |
| DB 저장 로직 | 높음 | 완전 재작성 |
최종 권장사항:
- 0_old는 알고리즘 참고용으로만 사용
- 경로, API, 컴포넌트 구조는 현재 프로젝트 표준 준수
- 통합 전 단위 테스트 작성 (경로 매핑, API 응답 검증)