Metadata-Version: 2.4
Name: steam-mongodb-client
Version: 0.4.3
Summary: Simple MongoDB/GridFS client for STEAM partner institutions
Author: GNU STEAM Project
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: pymongo<5,>=4.6
Provides-Extra: pcd
Requires-Dist: open3d>=0.19; extra == "pcd"
Requires-Dist: numpy<3,>=1.26; extra == "pcd"
Provides-Extra: registration
Requires-Dist: open3d>=0.19; extra == "registration"
Requires-Dist: numpy<3,>=1.26; extra == "registration"

# STEAM MongoDB Client

타 기관 사용자가 MongoDB/GridFS 기능을 간단한 Python 함수로 사용할 수 있도록 만든 배포용 패키지입니다.

## 1. 사용자 설치

PyPI에 배포한 뒤 사용자는 터미널에서 한 번만 설치합니다.

```powershell
pip install steam-mongodb-client
```

PCD를 Open3D 객체로 직접 읽을 사용자는 다음 중 하나를 실행합니다.

```powershell
pip install "steam-mongodb-client[pcd]"
```

또는

```powershell
pip install open3d
```

ICP 정합 기능까지 사용할 사용자는 다음 명령으로 설치합니다.

```powershell
pip install "steam-mongodb-client[registration]"
```

## 2. 기본 사용 순서

```python
from steam_mongodb import connect, search, download, close

connect(
    host="203.xxx.xxx.xxx",
    username="기관계정",
    password="기관비밀번호",
    ca_file=r"C:\mongodb-certs\ca.pem",
)

files = search(site="site", pcd_type="UAV_PCD")
print(files)

download(
    files[0]["file_id"],
    r"D:\STEAM_DATA\downloaded.pcd",
)

close()
```

## 3. 제공 함수

| 함수 | 용도 |
|---|---|
| `connect()` | MongoDB 연결 |
| `ping()` | 연결 확인 |
| `search()` | 파일 검색/조회 |
| `download()` | 파일 저장 |
| `read_pcd()` | PCD를 Open3D 객체로 읽기 |
| `registration()` | 두 PCD를 ICP 정합하고 Reg_PCD로 저장 |
| `upload()` | 파일 업로드 |
| `update()` | 파일명/메타데이터 수정 |
| `delete()` | GridFS 파일 삭제 |
| `close()` | 연결 종료 |

## 4. 검색 예시

```python
files = search(
    site="site",
    date="2026-08-15",
    pcd_type="UAV_PCD",
)
```

조건은 필요한 것만 입력하면 됩니다.

```python
files = search(site="site")
```

```python
files = search(filename="sample")
```

## 5. PCD 직접 읽기

```python
from steam_mongodb import read_pcd

pcd = read_pcd(file_id)
print(pcd)
```

`read_pcd()`는 임시 PCD 파일을 만든 뒤 Open3D 객체로 읽고 임시 파일을 자동 삭제합니다.

## 6. PCD 객체 기반 자동 정합 및 Reg_PCD 저장

`read_pcd()`로 MongoDB의 PCD를 실제 Open3D `PointCloud` 객체로 읽은 뒤 정합합니다.
`registration()`의 첫 번째 인자는 이동할 UGV(source), 두 번째 인자는 기준 UAV(target)입니다.

```python
from steam_mongodb import read_pcd, registration

ugv = read_pcd("UGV_file_id")
uav = read_pcd("UAV_file_id")

result = registration(ugv, uav)

print("scale:", result["scale"])
print("fitness:", result["fitness"])
print("RMSE:", result["inlier_rmse"])
print("Reg_PCD file_id:", result["file_id"])
```

현재 버전은 두 PCD의 원점과 크기가 크게 다른 경우를 고려하여 다음 순서로 처리합니다.

1. `read_pcd()`가 GridFS 원본 PCD를 Open3D `PointCloud`로 반환
2. UGV/UAV의 metadata와 포인트 유효성 확인
3. 각 PCD의 robust 중심과 대표 크기 계산
4. 각 PCD를 정규화하여 큰 전역좌표와 uniform scale 차이 제거
5. FPFH-RANSAC 및 PCA 후보로 초기 회전/방향 탐색
6. 대응점으로 uniform scale + rotation + translation(Similarity Transform) 추정
7. UGV를 UAV 좌표계/크기로 초기 변환
8. target 크기에 맞춘 adaptive voxel로 coarse → medium → fine ICP 수행
9. 원본 UGV 전체에 최종 변환 적용
10. UAV + 정합 UGV를 병합하여 `Reg_PCD`로 MongoDB에 자동 저장

`registration()`은 `voxel_size=0.5`처럼 큰 값이 입력되어도 UAV 공간 크기에 비해 지나치게 크면 자동으로 줄여 사용합니다.

출력되는 주요 진단값은 다음과 같습니다.

```text
UGV/UAV XYZ 범위
단순 공간 크기 비율
초기 정렬 방식
추정 uniform scale
정규화 초기 Fitness / RMSE
Similarity 대응점 수
coarse / medium / fine ICP Fitness / RMSE
최종 Fitness / RMSE
```

> 주의: 자동 Similarity 정합은 두 PCD 사이에 충분한 공통 구조가 있고, 두 데이터의 차이가 **uniform scale + rotation + translation**으로 설명될 수 있을 때 가장 잘 동작합니다. X/Y/Z 축이 서로 다른 비율로 왜곡된 데이터나 공통 영역이 거의 없는 PCD는 원본 좌표계 설정을 먼저 확인해야 합니다.

## 7. 업로드

```python
from steam_mongodb import upload

file_id = upload(
    file_path=r"D:\STEAM_DATA\sample.pcd",
    site="site",
    date="2026-08-15",
    pcd_type="UAV_PCD",
)

print(file_id)
```

## 8. 수정

```python
from steam_mongodb import update

update(
    file_id,
    pcd_type="Reg_PCD",
)
```

## 9. 삭제

```python
from steam_mongodb import delete

delete(file_id)
```

삭제 권한이 있는 계정에서만 제공하는 것을 권장합니다.

## 10. 코드 보호 구조

사용자가 설치하는 wheel에는 `_core.pyx` 원본을 넣지 않고 Cython으로 컴파일된 확장 모듈을 넣도록 구성되어 있습니다.

사용자가 일반적으로 볼 수 있는 `__init__.py`에는 아래와 같이 공개 함수 이름만 존재합니다.

```python
from ._core import connect, search, download, read_pcd, registration, upload, update, delete, close
```

따라서 일반적인 순수 Python 패키지보다 내부 구현 코드를 쉽게 열어보거나 수정하기 어렵습니다.

단, 사용자 PC에 설치된 프로그램을 기술적으로 100% 수정 불가능하게 만드는 것은 불가능합니다. 이 구조의 목적은 **원본 소스 비공개 + 일반 사용자의 임의 수정 방지 + 단순한 함수 호출 인터페이스 제공**입니다.

## 11. GitHub 권장 구조

### 개발 저장소

- GitHub Private Repository
- 관리자/개발자만 접근
- `_core.pyx` 포함
- MongoDB 비밀번호, 인증서 개인키, 실제 기관 비밀번호는 절대 업로드 금지

### 배포

태그를 push하면 GitHub Actions가 Windows용 wheel을 만들고 PyPI에 wheel만 배포하도록 설정되어 있습니다.

```powershell
git tag v0.4.3
git push origin v0.4.3
```

PyPI의 Trusted Publisher 설정이 먼저 필요합니다.

## 12. 중요 보안 원칙

1. MongoDB 관리자 계정 비밀번호를 패키지에 넣지 않기
2. 기관별 계정과 비밀번호를 사용자에게 따로 전달하기
3. 실제 IP, 인증서 개인키, 비밀번호를 GitHub 코드에 하드코딩하지 않기
4. 기관 계정별 MongoDB 권한을 필요한 범위로 제한하기
5. 일반 조회 기관에 `delete()` 권한이 필요 없다면 MongoDB 계정 권한 자체에서 삭제를 막기
6. 소스 배포판(`.tar.gz`)은 공개 배포하지 않고 compiled wheel만 배포하기

## 13. 현재 기본 GridFS 구조

기본 bucket 이름은 `data`입니다.

따라서 MongoDB에서는 일반적으로 다음 두 컬렉션을 사용합니다.

```text
data.files
data.chunks
```

현재 버전의 bucket 이름은 패키지 내부에서 `data`로 고정되어 있습니다.

## 14. 인증 DB가 다른 경우

기본값은 다음과 같습니다.

```python
auth_db="steam_db"
```

기본 설정을 명시적으로 입력하려면 다음과 같이 사용합니다.

```python
connect(
    ...,
    auth_db="steam_db",
)
```

기관 계정이 다른 인증 DB에 생성되어 있다면 해당 DB 이름을 `auth_db`에 입력합니다.
예를 들어 `admin`에서 계정을 생성했다면 `auth_db="admin"`을 사용합니다.
