diff --git a/.claude/settings.json b/.claude/settings.json
index 57308c6..8ee494f 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -8,7 +8,8 @@
"Edit(/.claude/skills/review/**)",
"Edit(/.claude/agents/**)",
"Edit(/.claude/hooks/**)",
- "mcp__gitea__issue_write"
+ "mcp__gitea__issue_write",
+ "PowerShell($env:GEO_DATA_DIR=\"d:\\\\MYCLAUDE_PROJECT\\\\abcvideo\\\\samplevideo\"; $env:VIDEOS_DIR=\"d:\\\\MYCLAUDE_PROJECT\\\\abcvideo\\\\storage\\\\videos\"; npm run dev)"
]
},
"hooks": {
diff --git a/docs/history.zip b/docs/history.zip
new file mode 100644
index 0000000..25277fd
Binary files /dev/null and b/docs/history.zip differ
diff --git a/docs/history/2026-04-28_미니맵-미표시-원인분석.md b/docs/history/2026-04-28_미니맵-미표시-원인분석.md
new file mode 100644
index 0000000..dae90bc
--- /dev/null
+++ b/docs/history/2026-04-28_미니맵-미표시-원인분석.md
@@ -0,0 +1,42 @@
+# 2026-04-28 미니맵 미표시 원인 분석 및 수정
+
+## 작업 내용
+새로운 서버에 배포 후 RoutePanel 미니맵이 표시되지 않는 원인 분석 및 수정
+
+## 원인
+
+1. **`GEO_DATA_DIR` 미설정**: 기본값이 `samplevideo/` 상대 경로인데 새 서버에 해당 폴더 없음
+2. **`loadFrames()` crash**: `_dataDir`이 존재하지 않아도 `fs.readdirSync()` 호출 → 예외 발생 → `/api/geo/frames` 500 반환
+3. **RoutePanel 렌더 가드**: `stations.length === 0` 이면 `null` 반환 → 미니맵 완전히 숨김
+4. **에러 무시**: fetch `.catch(() => {})` 로 서버 500 에러가 조용히 무시됨
+
+## 수정 사항
+
+- `server/src/services/geoMatch.ts`: `loadFrames()`에 `fs.existsSync(_dataDir)` 체크 추가 (crash → 빈 배열 반환)
+- `loadFrames()`, `loadPois()` 양쪽에 `[geo]` 경고 로그 추가 (어떤 파일이 없는지 즉시 파악 가능)
+- 불필요한 미사용 변수(`csvPath`) 제거
+
+## 새 서버 설정 방법
+
+```powershell
+$env:GEO_DATA_DIR="C:\경로\samplevideo"
+$env:VIDEOS_DIR="C:\경로\videos"
+npm run dev:server
+```
+
+필요한 디렉토리 구조:
+```
+{GEO_DATA_DIR}/
+├── 하행)회덕-대전조차장.csv ← 드론 비행 데이터
+└── building/
+ ├── *POI*위경도*.csv
+ └── *측점*위경도*.csv
+```
+
+## GeoSearch 기능 확인
+- "건물 → 프레임" 탭: 측점/건물명 검색 → 카메라 시야 내 프레임 목록 → 클릭 시 이동
+- "프레임 → 건물" 탭: 현재 프레임에서 보이는 POI/측점 목록 표시
+- RoutePanel: 세로 드래그로 km 위치 seek
+
+**소요 시간**: 20분
+**Context 사용량**: input 45k / output 8k tokens
diff --git a/pythonsource/advanced_tuner_v2.py b/pythonsource/advanced_tuner_v2.py
new file mode 100644
index 0000000..bda6aca
--- /dev/null
+++ b/pythonsource/advanced_tuner_v2.py
@@ -0,0 +1,560 @@
+import sys
+import os
+import re
+import cv2
+import numpy as np
+import pandas as pd
+from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
+ QLabel, QLineEdit, QPushButton, QFileDialog, QTabWidget,
+ QSlider, QDoubleSpinBox, QProgressBar, QComboBox, QGroupBox, QFormLayout,
+ QSpinBox)
+from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
+from PyQt5.QtGui import QImage, QPixmap
+from scipy.spatial.transform import Rotation as R
+from pyproj import Transformer
+
+# =================================================================
+# [NEXT GEN] advanced_tuner_v2.py: Streamlined GIS GUI Tuner
+# 설계 원칙:
+# 1. MP4 + SRT + CSV (WGS84) 워크플로우 통합
+# 2. 실시간 좌표 변환 (Lat/Lon -> EPSG:5186)
+# 3. 사용자 친화적 튜닝 인터페이스 제공
+# =================================================================
+
+class SRTParser:
+ @staticmethod
+ def parse(srt_path):
+ data_dict = {}
+ if not os.path.exists(srt_path): return data_dict
+ try:
+ with open(srt_path, 'r', encoding='utf-8', errors='ignore') as f:
+ content = f.read()
+ if "latitude" not in content.lower():
+ with open(srt_path, 'r', encoding='cp949', errors='ignore') as f:
+ content = f.read()
+
+ blocks = content.split('\n\n')
+ for block in blocks:
+ f_match = re.search(r'FrameCnt:\s*(\d+)', block)
+ if not f_match: continue
+ idx = int(f_match.group(1))
+
+ lat = float(re.search(r'latitude:\s*([\d\.-]+)', block).group(1))
+ lon = float(re.search(r'longitude:\s*([\d\.-]+)', block).group(1))
+ alt = float(re.search(r'abs_alt:\s*([\d\.-]+)', block).group(1))
+ yaw = float(re.search(r'gb_yaw:\s*([\d\.-]+)', block).group(1))
+ pitch = float(re.search(r'gb_pitch:\s*([\d\.-]+)', block).group(1))
+ roll = float(re.search(r'gb_roll:\s*([\d\.-]+)', block).group(1))
+ focal = float(re.search(r'focal_len:\s*([\d\.-]+)', block).group(1))
+
+ data_dict[idx] = {
+ 'lat': lat, 'lon': lon, 'alt': alt,
+ 'yaw': yaw, 'pitch': pitch, 'roll': roll,
+ 'focal': focal
+ }
+ # Post-process: Filling gaps and Smoothing
+ if not data_dict: return {}
+
+ indices = sorted(data_dict.keys())
+ min_idx, max_idx = indices[0], indices[-1]
+
+ # 1. Interpolate Gaps
+ all_indices = np.arange(min_idx, max_idx + 1)
+ new_data = {}
+
+ fields = ['lat', 'lon', 'alt', 'yaw', 'pitch', 'roll', 'focal']
+ temp_arrays = {f: [] for f in fields}
+ for idx in indices:
+ for f in fields:
+ temp_arrays[f].append(data_dict[idx][f])
+
+ interp_arrays = {}
+ for f in fields:
+ # Handle Yaw wrapping for smoother rotation (Optional but safer)
+ if f == 'yaw':
+ y_arr = np.array(temp_arrays[f])
+ # Ensure continuous angles
+ y_arr = np.unwrap(np.radians(y_arr))
+ interp_y = np.interp(all_indices, indices, y_arr)
+ # 2. Smooth (Moving Average)
+ smooth_y = np.convolve(interp_y, np.ones(5)/5, mode='same')
+ interp_arrays[f] = np.degrees(smooth_y)
+ else:
+ interp_f = np.interp(all_indices, indices, temp_arrays[f])
+ # 2. Smooth (Moving Average)
+ interp_arrays[f] = np.convolve(interp_f, np.ones(5)/5, mode='same')
+
+ for i, idx in enumerate(all_indices):
+ new_data[int(idx)] = {f: interp_arrays[f][i] for f in fields}
+
+ return new_data
+ except Exception as e:
+ print(f"SRT Error: {e}")
+ return {}
+
+class RenderWorker(QThread):
+ progress = pyqtSignal(int)
+ finished = pyqtSignal(str)
+
+ def __init__(self, params):
+ super().__init__()
+ self.p = params
+ self.is_running = True
+
+ def stop(self):
+ self.is_running = False
+
+ def run(self):
+ try:
+ cap = cv2.VideoCapture(self.p['video_path'])
+ original_fps = cap.get(cv2.CAP_PROP_FPS)
+ cap.set(cv2.CAP_PROP_POS_FRAMES, self.p['range'][0])
+
+ target_w, target_h = self.p['resolution']
+ target_fps = self.p['fps'] if self.p['fps'] > 0 else original_fps
+ start_f, end_f = self.p['range']
+ total_work = end_f - start_f + 1
+
+ fourcc = cv2.VideoWriter_fourcc(*self.p['codec'])
+ out = cv2.VideoWriter(self.p['output_path'], fourcc, target_fps, (target_w, target_h))
+
+ transformer = Transformer.from_crs("epsg:4326", "epsg:5186")
+
+ # Pre-swap line points if needed
+ eff_line_pts = self.p['line_pts']
+ if self.p['swap_xy']:
+ eff_line_pts = eff_line_pts.copy()
+ eff_line_pts[:, [0, 1]] = eff_line_pts[:, [1, 0]]
+
+ for f_idx in range(start_f, end_f + 1):
+ if not self.is_running: break
+ ret, frame = cap.read()
+ if not ret: break
+
+ # Check for Sync
+ if f_idx in self.p['srt_data']:
+ meta = self.p['srt_data'][f_idx]
+ dx, dy = transformer.transform(meta['lat'], meta['lon'])
+
+ if self.p['swap_xy']:
+ dx, dy = dy, dx
+
+ # Resize frame if needed
+ original_h, original_w = frame.shape[:2]
+ if (target_w, target_h) != (original_w, original_h):
+ draw_frame = cv2.resize(frame, (target_w, target_h))
+ else:
+ draw_frame = frame.copy()
+
+ drone_pos = np.array([dx + self.p['off_x'], dy + self.p['off_y'], meta['alt'] + self.p['off_z']])
+ rvec, tvec, K = self.get_proj(meta, drone_pos, target_w, target_h)
+ R_w2c, _ = cv2.Rodrigues(rvec)
+ pts_cam = (eff_line_pts @ R_w2c.T) + tvec.T
+
+ for i in range(0, len(pts_cam), 2):
+ p1c, p2c = pts_cam[i], pts_cam[i+1]
+ if p1c[2] < 0.1 and p2c[2] < 0.1: continue
+ if p1c[2] < 0.1 or p2c[2] < 0.1:
+ t = (0.1 - p1c[2]) / (p2c[2] - p1c[2])
+ p_mid = p1c + t * (p2c - p1c)
+ if p1c[2] < 0.1: p1c = p_mid
+ else: p2c = p_mid
+
+ u1 = int(K[0, 0] * (p1c[0] / p1c[2]) + K[0, 2])
+ v1 = int(K[1, 1] * (p1c[1] / p1c[2]) + K[1, 2])
+ u2 = int(K[0, 0] * (p2c[0] / p2c[2]) + K[0, 2])
+ v2 = int(K[1, 1] * (p2c[1] / p2c[2]) + K[1, 2])
+
+ ret_cli, pt1, pt2 = cv2.clipLine((0, 0, target_w, target_h), (u1, v1), (u2, v2))
+ if ret_cli:
+ cv2.line(draw_frame, pt1, pt2, (0, 0, 255), 10)
+ out.write(draw_frame)
+ else:
+ if (target_w, target_h) != (frame.shape[1], frame.shape[0]):
+ out.write(cv2.resize(frame, (target_w, target_h)))
+ else:
+ out.write(frame)
+
+ self.progress.emit(int(((f_idx - start_f + 1) / total_work) * 100))
+
+
+ cap.release()
+ out.release()
+ self.finished.emit(self.p['output_path'])
+ except Exception as e:
+ self.finished.emit(f"Error: {e}")
+
+ def get_proj(self, meta, drone_pos, w, h):
+ yaw = np.radians(meta['yaw'] + self.p['off_yaw'])
+ pitch = np.radians(meta['pitch'] + self.p['off_pitch'])
+ roll = np.radians(meta['roll'] + self.p['off_roll'])
+
+ R_b2w = (R.from_euler('z', -yaw) * R.from_euler('x', pitch) * R.from_euler('y', roll)).as_matrix()
+ R_w2c = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]]) @ R_b2w.T
+ rvec, _ = cv2.Rodrigues(R_w2c)
+ tvec = -R_w2c @ drone_pos
+
+ f_px = (self.p['focal'] / self.p['sensor_w']) * w
+ K = np.array([[f_px, 0, w/2], [0, f_px, h/2], [0, 0, 1]])
+ return rvec, tvec, K
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("Advanced GIS Tuner v2 (Streamlined)")
+ self.resize(1280, 850)
+
+ self.srt_data = {}
+ self.line_points = np.array([])
+ self.transformer = Transformer.from_crs("epsg:4326", "epsg:5186")
+
+ self.init_ui()
+
+ def init_ui(self):
+ tabs = QTabWidget()
+ self.setCentralWidget(tabs)
+
+ # --- Tab 1: Data Input ---
+ tab1 = QWidget()
+ layout1 = QVBoxLayout()
+ form1 = QFormLayout()
+
+ self.btn_video = QPushButton("Find MP4")
+ self.txt_video = QLineEdit("하행)회덕-대전조차장.MP4")
+ self.btn_video.clicked.connect(lambda: self.find_file(self.txt_video, "Video (*.mp4)"))
+ form1.addRow(self.btn_video, self.txt_video)
+
+ self.btn_srt = QPushButton("Find SRT")
+ self.txt_srt = QLineEdit("하행)회덕-대전조차장.srt")
+ self.btn_srt.clicked.connect(lambda: self.find_file(self.txt_srt, "SRT (*.srt)"))
+ form1.addRow(self.btn_srt, self.txt_srt)
+
+ self.btn_csv = QPushButton("Find CSV (Lat/Lon/H)")
+ self.txt_csv = QLineEdit("center.csv")
+ self.btn_csv.clicked.connect(lambda: self.find_file(self.txt_csv, "CSV (*.csv)"))
+ form1.addRow(self.btn_csv, self.txt_csv)
+
+ layout1.addLayout(form1)
+ self.btn_load = QPushButton("LOAD ALL DATA")
+ self.btn_load.setStyleSheet("background-color: #4CAF50; color: white; height: 50px; font-weight: bold;")
+ self.btn_load.clicked.connect(self.load_all_data)
+ layout1.addWidget(self.btn_load)
+ layout1.addStretch()
+ tab1.setLayout(layout1)
+ tabs.addTab(tab1, "1. 자료입력")
+
+ # --- Tab 2: Tuner ---
+ tab2 = QWidget()
+ hbox2 = QHBoxLayout()
+
+ # Left: Preview
+ vbox_prev = QVBoxLayout()
+ self.lbl_preview = QLabel("Video Preview (Load Data First)")
+ self.lbl_preview.setAlignment(Qt.AlignCenter)
+ self.lbl_preview.setStyleSheet("border: 2px solid gray; background-color: black;")
+ self.lbl_preview.setMinimumSize(800, 450)
+ vbox_prev.addWidget(self.lbl_preview)
+
+ self.sld_frame = QSlider(Qt.Horizontal)
+ self.sld_frame.valueChanged.connect(self.update_sync_frame)
+ self.spn_frame = QDoubleSpinBox()
+ self.spn_frame.setDecimals(0)
+ self.spn_frame.setSingleStep(1)
+ self.spn_frame.valueChanged.connect(self.update_sync_frame)
+
+ self.btn_play = QPushButton("▶ PLAY")
+ self.btn_play.setCheckable(True)
+ self.btn_play.clicked.connect(self.toggle_play)
+
+ self.play_timer = QTimer()
+ self.play_timer.timeout.connect(self.next_frame)
+
+ frame_hbox = QHBoxLayout()
+ frame_hbox.addWidget(self.btn_play)
+ frame_hbox.addWidget(QLabel("Frame:"))
+ frame_hbox.addWidget(self.spn_frame)
+ frame_hbox.addWidget(self.sld_frame, 10)
+ vbox_prev.addLayout(frame_hbox)
+
+ hbox2.addLayout(vbox_prev, 7)
+
+ # Right: Controls
+ vbox_ctrl = QVBoxLayout()
+ group_offsets = QGroupBox("Offsets (Yaw/Pitch/Roll/XYZ)")
+ form2 = QFormLayout()
+
+ self.chk_swap_xy = QPushButton("Swap XY Coordinates: OFF")
+ self.chk_swap_xy.setCheckable(True)
+ self.chk_swap_xy.clicked.connect(self.toggle_swap_xy)
+ form2.addRow("Axis:", self.chk_swap_xy)
+
+ self.spn_yaw = self.create_spinbox(-180, 180, 0, form2, "Yaw Off")
+ self.spn_pitch = self.create_spinbox(-180, 180, 0, form2, "Pitch Off")
+ self.spn_roll = self.create_spinbox(-180, 180, 0, form2, "Roll Off")
+ form2.addRow(QLabel("
"))
+ self.spn_off_x = self.create_spinbox(-1000, 1000, 0, form2, "Pos X Off (m)")
+ self.spn_off_y = self.create_spinbox(-1000, 1000, 0, form2, "Pos Y Off (m)")
+ self.spn_off_z = self.create_spinbox(-1000, 1000, 0, form2, "Pos Z Off (m)")
+ form2.addRow(QLabel("
"))
+ self.spn_focal = self.create_spinbox(1, 200, 24, form2, "Focal (mm)")
+ self.spn_sensor = self.create_spinbox(1, 100, 36, form2, "Sensor W (mm)")
+
+ group_offsets.setLayout(form2)
+ vbox_ctrl.addWidget(group_offsets)
+ vbox_ctrl.addStretch()
+ hbox2.addLayout(vbox_ctrl, 3)
+
+ tab2.setLayout(hbox2)
+ tabs.addTab(tab2, "2. 튜너")
+
+ # --- Tab 3: Export ---
+ tab3 = QWidget()
+ vbox3 = QVBoxLayout()
+ form3 = QFormLayout()
+
+ self.cmb_res = QComboBox()
+ self.cmb_res.addItems(["Original", "4K (3840x2160)", "2K (2560x1440)", "1080p (1920x1080)"])
+ form3.addRow("Resolution", self.cmb_res)
+
+ self.cmb_fps = QComboBox()
+ self.cmb_fps.addItems(["Original", "60", "30"])
+ form3.addRow("FPS", self.cmb_fps)
+
+ self.cmb_codec = QComboBox()
+ self.cmb_codec.addItems(["H.264 (avc1)", "MPEG-4 (mp4v)"])
+ form3.addRow("Codec", self.cmb_codec)
+
+ form3.addRow(QLabel("
"))
+ self.spn_start = QSpinBox()
+ self.spn_start.setRange(0, 999999)
+ form3.addRow("Start Frame", self.spn_start)
+
+ self.spn_end = QSpinBox()
+ self.spn_end.setRange(0, 999999)
+ form3.addRow("End Frame", self.spn_end)
+
+ vbox3.addLayout(form3)
+ self.btn_export = QPushButton("START EXPORT")
+ self.btn_export.setStyleSheet("height: 60px; font-weight: bold; background-color: #f44336; color: white;")
+ self.btn_export.clicked.connect(self.start_export)
+ vbox3.addWidget(self.btn_export)
+
+ self.pbar = QProgressBar()
+ vbox3.addWidget(self.pbar)
+ vbox3.addStretch()
+ tab3.setLayout(vbox3)
+ tabs.addTab(tab3, "3. 출력")
+
+ def create_spinbox(self, min_v, max_v, def_v, layout, label):
+ sb = QDoubleSpinBox()
+ sb.setRange(min_v, max_v)
+ sb.setValue(def_v)
+ sb.setDecimals(2)
+ sb.setSingleStep(0.1)
+ sb.valueChanged.connect(self.update_preview)
+ layout.addRow(label, sb)
+ return sb
+
+ def toggle_play(self):
+ if self.btn_play.isChecked():
+ self.btn_play.setText("■ PAUSE")
+ # Calculate interval based on FPS (or default 33ms for 30fps)
+ cap = cv2.VideoCapture(self.txt_video.text())
+ fps = cap.get(cv2.CAP_PROP_FPS)
+ cap.release()
+ interval = int(1000 / fps) if fps > 0 else 33
+ self.play_timer.start(interval)
+ else:
+ self.btn_play.setText("▶ PLAY")
+ self.play_timer.stop()
+
+ def next_frame(self):
+ curr = self.sld_frame.value()
+ if curr < self.total_frames - 1:
+ self.sld_frame.setValue(curr + 1)
+ else:
+ self.btn_play.setChecked(False)
+ self.toggle_play()
+
+ def toggle_swap_xy(self):
+ if self.chk_swap_xy.isChecked():
+ self.chk_swap_xy.setText("Swap XY Coordinates: ON")
+ else:
+ self.chk_swap_xy.setText("Swap XY Coordinates: OFF")
+ self.update_preview()
+
+ def update_sync_frame(self, val):
+ # 도우미: 슬라이더와 스핀박스 동기화
+ sender = self.sender()
+ if sender == self.sld_frame:
+ self.spn_frame.blockSignals(True)
+ self.spn_frame.setValue(val)
+ self.spn_frame.blockSignals(False)
+ else:
+ self.sld_frame.blockSignals(True)
+ self.sld_frame.setValue(int(val))
+ self.sld_frame.blockSignals(False)
+ self.update_preview()
+
+ def find_file(self, line_edit, filt):
+ path, _ = QFileDialog.getOpenFileName(self, "Select File", "", filt)
+ if path: line_edit.setText(path)
+
+ def load_all_data(self):
+ print("Loading...")
+ self.srt_data = SRTParser.parse(self.txt_srt.text())
+
+ # Load CSV
+ try:
+ df = pd.read_csv(self.txt_csv.text(), encoding='cp949')
+ # lat, lon, 타원체고(h)
+ raw_pts = []
+ for _, row in df.iterrows():
+ x, y = self.transformer.transform(row['lat'], row['lon'])
+ raw_pts.append([x, y, row['타원체고(h)']])
+
+ # Reconstruct segments: 0-1, 1-2, 2-3...
+ seg_pts = []
+ for i in range(len(raw_pts)-1):
+ seg_pts.extend([raw_pts[i], raw_pts[i+1]])
+
+ self.line_points = np.array(seg_pts, dtype=np.float64)
+ print(f"Loaded {len(self.line_points)//2} segments.")
+ except Exception as e:
+ print(f"CSV Load Error: {e}")
+
+ # Video Info
+ cap = cv2.VideoCapture(self.txt_video.text())
+ self.total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
+ self.video_fps = cap.get(cv2.CAP_PROP_FPS)
+
+ self.sld_frame.setRange(0, self.total_frames - 1)
+ self.spn_frame.setRange(0, self.total_frames - 1)
+ self.spn_start.setRange(0, self.total_frames - 1)
+ self.spn_end.setRange(0, self.total_frames - 1)
+ self.spn_end.setValue(self.total_frames - 1)
+ cap.release()
+
+ self.update_preview()
+
+ def update_preview(self):
+ if not self.srt_data or self.line_points.size == 0: return
+
+ f_idx = self.sld_frame.value()
+ cap = cv2.VideoCapture(self.txt_video.text())
+ cap.set(cv2.CAP_PROP_POS_FRAMES, f_idx)
+ ret, frame = cap.read()
+ cap.release()
+
+ if not ret: return
+
+ h, w = frame.shape[:2]
+ if f_idx in self.srt_data:
+ meta = self.srt_data[f_idx]
+
+ dx, dy = self.transformer.transform(meta['lat'], meta['lon'])
+
+ # Swap Logic
+ if self.chk_swap_xy.isChecked():
+ dx, dy = dy, dx
+ line_pts_eff = self.line_points.copy()
+ line_pts_eff[:, [0, 1]] = line_pts_eff[:, [1, 0]]
+ else:
+ line_pts_eff = self.line_points
+
+ drone_pos = np.array([dx + self.spn_off_x.value(),
+ dy + self.spn_off_y.value(),
+ meta['alt'] + self.spn_off_z.value()])
+
+ # 실시간 디버그 로그 (콘솔 출력)
+ print(f"[Frame {f_idx}] XY_Order: {'Y,X' if self.chk_swap_xy.isChecked() else 'X,Y'} | Drone X={drone_pos[0]:.2f}, Y={drone_pos[1]:.2f}")
+
+ # Projection
+ yaw = np.radians(meta['yaw'] + self.spn_yaw.value())
+ pitch = np.radians(meta['pitch'] + self.spn_pitch.value())
+ roll = np.radians(meta['roll'] + self.spn_roll.value())
+
+ r_yaw = R.from_euler('z', -yaw)
+ r_pitch = R.from_euler('x', pitch)
+ r_roll = R.from_euler('y', roll)
+
+ R_b2w = (r_yaw * r_pitch * r_roll).as_matrix()
+ R_align = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
+ R_w2c = R_align @ R_b2w.T
+
+ rvec, _ = cv2.Rodrigues(R_w2c)
+ tvec = -R_w2c @ drone_pos
+
+ f_px = (self.spn_focal.value() / self.spn_sensor.value()) * w
+ K = np.array([[f_px, 0, w/2], [0, f_px, h/2], [0, 0, 1]])
+
+ pts_cam = (line_pts_eff @ R_w2c.T) + tvec.T
+ for i in range(0, len(pts_cam), 2):
+ p1c, p2c = pts_cam[i], pts_cam[i+1]
+ if p1c[2] < 0.1 and p2c[2] < 0.1: continue
+ if p1c[2] < 0.1 or p2c[2] < 0.1:
+ t = (0.1 - p1c[2]) / (p2c[2] - p1c[2])
+ p_mid = p1c + t * (p2c - p1c)
+ if p1c[2] < 0.1: p1c = p_mid
+ else: p2c = p_mid
+
+ u1 = int(K[0, 0] * (p1c[0] / p1c[2]) + K[0, 2])
+ v1 = int(K[1, 1] * (p1c[1] / p1c[2]) + K[1, 2])
+ u2 = int(K[0, 0] * (p2c[0] / p2c[2]) + K[0, 2])
+ v2 = int(K[1, 1] * (p2c[1] / p2c[2]) + K[1, 2])
+
+ ret_cli, pt1, pt2 = cv2.clipLine((0, 0, w, h), (u1, v1), (u2, v2))
+ if ret_cli:
+ cv2.line(frame, pt1, pt2, (0, 0, 255), 10)
+
+ # Convert to QPixmap
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
+ img = QImage(frame.data, w, h, w*3, QImage.Format_RGB888)
+ pixmap = QPixmap.fromImage(img).scaled(self.lbl_preview.width(), self.lbl_preview.height(), Qt.KeepAspectRatio)
+ self.lbl_preview.setPixmap(pixmap)
+
+ def start_export(self):
+ res_map = {"Original": (0, 0), "4K (3840x2160)": (3840, 2160), "2K (2560x1440)": (2560, 1440), "1080p (1920x1080)": (1920, 1080)}
+ codec_map = {"H.264 (avc1)": "avc1", "MPEG-4 (mp4v)": "mp4v"}
+
+ target_res = res_map[self.cmb_res.currentText()]
+ if target_res == (0, 0):
+ cap = cv2.VideoCapture(self.txt_video.text())
+ target_res = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
+ cap.release()
+
+ params = {
+ 'video_path': self.txt_video.text(),
+ 'srt_data': self.srt_data,
+ 'line_pts': self.line_points,
+ 'off_yaw': self.spn_yaw.value(),
+ 'off_pitch': self.spn_pitch.value(),
+ 'off_roll': self.spn_roll.value(),
+ 'off_x': self.spn_off_x.value(),
+ 'off_y': self.spn_off_y.value(),
+ 'off_z': self.spn_off_z.value(),
+ 'focal': self.spn_focal.value(),
+ 'sensor_w': self.spn_sensor.value(),
+ 'resolution': target_res,
+ 'fps': int(self.cmb_fps.currentText()) if self.cmb_fps.currentText() != "Original" else 0,
+ 'range': (self.spn_start.value(), self.spn_end.value()),
+ 'swap_xy': self.chk_swap_xy.isChecked(),
+ 'codec': codec_map[self.cmb_codec.currentText()],
+ 'output_path': "output_tuner_v2.mp4"
+ }
+
+ self.btn_export.setEnabled(False)
+ self.worker = RenderWorker(params)
+ self.worker.progress.connect(self.pbar.setValue)
+ self.worker.finished.connect(self.export_done)
+ self.worker.start()
+
+ def export_done(self, msg):
+ self.btn_export.setEnabled(True)
+ print(f"Export Result: {msg}")
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec_())
diff --git a/pythonsource/input/building/하행)회덕-대전조차장_POI_XY값.csv b/pythonsource/input/building/하행)회덕-대전조차장_POI_XY값.csv
new file mode 100644
index 0000000..98ad202
--- /dev/null
+++ b/pythonsource/input/building/하행)회덕-대전조차장_POI_XY값.csv
@@ -0,0 +1,41 @@
+title,category_clean,address_road,address_jibun,lat,lon,z
+ѱö忪,幰, Ƹ 166, 426,38.5105183,-3457.077306,14.93833585
+,幰, 1419, 172-4,91.97154721,-2425.164917,17.43774457
+,幰, 761 48, 262-1,187.2874319,-2532.38759,25.45520444
+ȸ,幰, 761 50, 58-4,209.2757755,-2594.655793,22.83119626
+,幰, 1402, 266-22,44.48265487,-2625.782598,11.92308469
+,幰, 1392 19, 269-16,85.48810915,-2727.805909,12.88381619
+ ,幰, 741 52, 290-2,249.229071,-2722.316827,14.40417523
+ֿ÷ƼѳóƮ,幰,, 51-9,304.937541,-2800.194266,18.89580197
+â,幰, Ƹ 166, 540,168.4670337,-3070.22605,14.899754
+ǥ ,幰, Ƹ 178, 426-1,163.6763012,-3308.164519,14.87806363
+ǥ,幰, Ƹ 178, 426-1,156.1322678,-3347.813475,14.83134885
+ijȽ,幰, ź115ȱ 25, Ŵ뵿 411-50,-493.0889954,-1171.866346,23.5801167
+,幰, ź115ȱ 15, Ŵ뵿 411-25,-494.390968,-1223.694574,27.74913449
+ﺸ,幰, Ƹ55 162, Ŵ뵿 446,-605.4733056,-1283.873731,2.79518933
+̿,幰, Ƹ55 156, Ŵ뵿 446-4,-598.2714644,-1352.19981,3.599010894
+,幰, Ƹ55 126, Ŵ뵿 437-22,-605.4980966,-1570.618123,1.855225036
+88ڿ,幰,, 200-1,-85.47358836,-2352.588534,21.30201382
+ Ʈ,幰, 1397 77, 203-4,-69.60296008,-2452.946447,22.22890515
+ȸȭ,幰, ȸ34 83, Ŵ뵿 129-1,22.93703649,-14.21495976,3.29909558
+ڿ,幰, ȸ34 73, Ŵ뵿 143-4,-4.326022471,-57.05726838,2.56787152
+ö,幰, ȸ34 19, Ŵ뵿 161-1,-152.6988919,-305.0545685,1.260082671
+ΰӵ,幰,,,-280.0231307,-439.6094122,3.734718749
+17ȣ(),幰,,,43.61010175,-2555.434246,10.2714848
+Ŵõ(),,,,-211.3748931,-324.2852559,2.016098449
+õ(),,,,10.0980771,-2459.483549,13.34468503
+õ(),,,,28.44331462,-2433.708587,13.66731305
+ȸ1(),,,,71.26732008,-2531.17875,12.39197583
+ȸ1(),,,,108.5555676,-2507.595674,13.37028546
+ȸ1(λ),,,,98.89002344,-2513.428321,12.97475476
+ȸõ(),,,,156.6135722,-2752.864405,13.50943036
+ȸõ(),,,,232.7118715,-2733.194393,15.0617146
+ȸõ(λ),,,,170.7372503,-2752.741497,13.51244778
+ȸõ(λ),,,,203.4135321,-2727.038754,14.89475293
+(),,,,231.0249244,-3240.340204,9.542900512
+"(,λ,)",,,,60.78639687,-3243.867529,8.17662091
+(λ),,,,159.7839769,-3239.047905,8.746838043
+ȸͳ(),ͳ,,,-564.2548179,-1925.009409,16.18040272
+ȸͳ(),ͳ,,,-529.036536,-1933.557941,22.58381459
+ȸ,,,,-19.02038509,4.710790739,8.626823852
+忪,,,,66.77359684,-3620.138085,21.01832242
diff --git a/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값.csv b/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값.csv
new file mode 100644
index 0000000..6e73c02
--- /dev/null
+++ b/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값.csv
@@ -0,0 +1,41 @@
+title,category_clean,address_road,address_jibun,lat,lon,z
+ѱö忪,幰, Ƹ 166, 426,36.371101,127.421776,14.93833585
+,幰, 1419, 172-4,36.380398,127.422422,17.43774457
+,幰, 761 48, 262-1,36.379428,127.423479,25.45520444
+ȸ,幰, 761 50, 58-4,36.378866,127.423721,22.83119626
+,幰, 1402, 266-22,36.378592,127.421883,11.92308469
+,幰, 1392 19, 269-16,36.377671,127.422335,12.88381619
+ ,幰, 741 52, 290-2,36.377714,127.42416,14.40417523
+ֿ÷ƼѳóƮ,幰,, 51-9,36.37701,127.424777,18.89580197
+â,幰, Ƹ 166, 540,36.374582,127.423243,14.899754
+ǥ ,幰, Ƹ 178, 426-1,36.372438,127.423178,14.87806363
+ǥ,幰, Ƹ 178, 426-1,36.372081,127.423092,14.83134885
+ijȽ,幰, ź115ȱ 25, Ŵ뵿 411-50,36.391715,127.415962,23.5801167
+,幰, ź115ȱ 15, Ŵ뵿 411-25,36.391248,127.415945,27.74913449
+ﺸ,幰, Ƹ55 162, Ŵ뵿 446,36.39071,127.414704,2.79518933
+̿,幰, Ƹ55 156, Ŵ뵿 446-4,36.390094,127.414781,3.599010894
+,幰, Ƹ55 126, Ŵ뵿 437-22,36.388126,127.41469,1.855225036
+88ڿ,幰,, 200-1,36.381059,127.420448,21.30201382
+ Ʈ,幰, 1397 77, 203-4,36.380154,127.42062,22.22890515
+ȸȭ,幰, ȸ34 83, Ŵ뵿 129-1,36.402127,127.42177,3.29909558
+ڿ,幰, ȸ34 73, Ŵ뵿 143-4,36.401742,127.421464,2.56787152
+ö,幰, ȸ34 19, Ŵ뵿 161-1,36.399513,127.419798,1.260082671
+ΰӵ,幰,,,36.398305,127.418372,3.734718749
+17ȣ(),幰,,,36.379226,127.421877,10.2714848
+Ŵõ(),,,,36.399342,127.419143,2.016098449
+õ(),,,,36.380092,127.421508,13.34468503
+õ(),,,,36.380324,127.421714,13.66731305
+ȸ1(),,,,36.379443,127.422186,12.39197583
+ȸ1(),,,,36.379655,127.422603,13.37028546
+ȸ1(λ),,,,36.379602,127.422495,12.97475476
+ȸõ(),,,,36.377442,127.423126,13.50943036
+ȸõ(),,,,36.377617,127.423975,15.0617146
+ȸõ(λ),,,,36.377443,127.423284,13.51244778
+ȸõ(λ),,,,36.377673,127.423649,14.89475293
+(),,,,36.373047,127.423932,9.542900512
+"(,λ,)",,,,36.373021,127.422035,8.17662091
+(λ),,,,36.373061,127.423138,8.746838043
+ȸͳ(),ͳ,,,36.384931,127.415133,16.18040272
+ȸͳ(),ͳ,,,36.384852,127.415525,22.58381459
+ȸ,,,,36.402299,127.421303,8.626823852
+忪,,,,36.36963,127.422083,21.01832242
diff --git a/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값_타원체고.csv b/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값_타원체고.csv
new file mode 100644
index 0000000..a7fbf41
--- /dev/null
+++ b/pythonsource/input/building/하행)회덕-대전조차장_POI_위경도값_타원체고.csv
@@ -0,0 +1,41 @@
+title,category_clean,address_road,address_jibun,lat,lon,z
+한국철도공사대전조차장역,지장물,대전 대덕구 아리랑로 166,대전 대덕구 읍내동 426,36.371101,127.421776,40.3873358
+공업사,지장물,대전 대덕구 대전로 1419,대전 대덕구 읍내동 172-4,36.380398,127.422422,42.8867446
+음식점,지장물,대전 대덕구 계족로761번길 48,대전 대덕구 읍내동 262-1,36.379428,127.423479,50.9042044
+교회,지장물,대전 대덕구 계족로761번길 50,대전 대덕구 읍내동 58-4,36.378866,127.423721,48.2801963
+공장,지장물,대전 대덕구 대전로 1402,대전 대덕구 읍내동 266-22,36.378592,127.421883,37.3720847
+음식점,지장물,대전 대덕구 대전로1392번길 19,대전 대덕구 읍내동 269-16,36.377671,127.422335,38.3328162
+오성우산 대전물류센터,지장물,대전 대덕구 계족로741번길 52,대전 대덕구 읍내동 290-2,36.377714,127.42416,39.8531752
+쌍용더플래티넘네이처아파트,지장물,,대전 대덕구 읍내동 51-9,36.37701,127.424777,44.344802
+창원기전,지장물,대전 대덕구 아리랑로 166,대전 대덕구 읍내동 540,36.374582,127.423243,40.348754
+삼표산업 대전공장,지장물,대전 대덕구 아리랑로 178,대전 대덕구 읍내동 426-1,36.372438,127.423178,40.3270636
+삼표레미콘,지장물,대전 대덕구 아리랑로 178,대전 대덕구 읍내동 426-1,36.372081,127.423092,40.2803489
+대전캐노픽스,지장물,대전 대덕구 신탄진로115번안길 25,대전 대덕구 신대동 411-50,36.391715,127.415962,49.0291167
+보명폴딩도어,지장물,대전 대덕구 신탄진로115번안길 15,대전 대덕구 신대동 411-25,36.391248,127.415945,53.1981345
+삼보목재,지장물,대전 대덕구 아리랑로55번길 162,대전 대덕구 신대동 446,36.39071,127.414704,28.2441893
+아이엘케이,지장물,대전 대덕구 아리랑로55번길 156,대전 대덕구 신대동 446-4,36.390094,127.414781,29.0480109
+대우사료공장,지장물,대전 대덕구 아리랑로55번길 126,대전 대덕구 신대동 437-22,36.388126,127.41469,27.304225
+88자원,지장물,,대전 대덕구 읍내동 200-1,36.381059,127.420448,46.7510138
+백송 아파트,지장물,대전 대덕구 대전로1397번길 77,대전 대덕구 읍내동 203-4,36.380154,127.42062,47.6779052
+회덕화물역,지장물,대전 대덕구 회덕로34번길 83,대전 대덕구 신대동 129-1,36.402127,127.42177,28.7480956
+대덕자원,지장물,대전 대덕구 회덕로34번길 73,대전 대덕구 신대동 143-4,36.401742,127.421464,28.0168715
+대전철거,지장물,대전 대덕구 회덕로34번길 19,대전 대덕구 신대동 161-1,36.399513,127.419798,26.7090827
+경부고속도로,지장물,,,36.398305,127.418372,29.1837187
+국도17호선(대전로),지장물,,,36.379226,127.421877,35.7204848
+신대천교(복),교량,,,36.399342,127.419143,27.4650984
+장등천교(상),교량,,,36.380092,127.421508,38.793685
+장등천교(하),교량,,,36.380324,127.421714,39.1163131
+회덕제1가도교(상),교량,,,36.379443,127.422186,37.8409758
+회덕제1가도교(하),교량,,,36.379655,127.422603,38.8192855
+회덕제1가도교(인상),교량,,,36.379602,127.422495,38.4237548
+회덕천교(상),교량,,,36.377442,127.423126,38.9584304
+회덕천교(하),교량,,,36.377617,127.423975,40.5107146
+회덕천교(상인상),교량,,,36.377443,127.423284,38.9614478
+회덕천교(하인상),교량,,,36.377673,127.423649,40.3437529
+법동가도교(하),교량,,,36.373047,127.423932,34.9919005
+"법동가도교(상,인상,고속)",교량,,,36.373021,127.422035,33.6256209
+법동가도교(인상),교량,,,36.373061,127.423138,34.195838
+회덕터널(상),터널,,,36.384931,127.415133,41.6294027
+회덕터널(하),터널,,,36.384852,127.415525,48.0328146
+회덕역,역사,,,36.402299,127.421303,34.0758239
+대전조차장역,역사,,,36.36963,127.422083,46.4673224
diff --git a/pythonsource/input/center.csv b/pythonsource/input/center.csv
new file mode 100644
index 0000000..089c98d
--- /dev/null
+++ b/pythonsource/input/center.csv
@@ -0,0 +1,225 @@
+id,lat,lon,ǥ(H),̵(N),Ÿü(h),67.39,41.57029343,,x,y
+0,36.4087069,127.4256135,44.5959549,25.449,70.0449549,2.6549549,3.02566147,0.37070657,238176.0008,423480.0717
+1,36.408246,127.4254695,44.15284348,25.449,69.60184348,2.21184348,2.58255005,0.37070657,238163.3099,423428.8698
+2,36.40798608,127.4253798,43.83666611,25.449,69.28566611,1.89566611,2.26637268,0.37070657,238155.3911,423399.9917
+3,36.40754207,127.4251955,43.25563812,25.449,68.70463812,1.31463812,1.68534469,0.37070657,238139.0769,423350.6482
+4,36.40743128,127.4251451,43.20756912,25.449,68.65656912,1.26656912,1.63727569,0.37070657,238134.6102,423338.3342
+5,36.40719869,127.425029,42.92715073,25.449,68.37615073,0.98615073,1.3568573,0.37070657,238124.3099,423312.4784
+6,36.40704302,127.4249459,42.94765854,25.448,68.39565854,1.00565854,1.37736511,0.37170657,238116.932,423295.1713
+7,36.40661489,127.4246681,42.49100494,25.448,67.93900494,0.54900494,0.92071151,0.37170657,238092.2226,423247.5531
+8,36.40648394,127.4245706,42.17842865,25.448,67.62642865,0.23642865,0.60813522,0.37170657,238083.5409,423232.9835
+9,36.40634883,127.4244596,42.3149147,25.447,67.7619147,0.3719147,0.74462127,0.37270657,238073.6501,423217.9469
+10,36.40619865,127.4243362,41.89298248,25.447,67.33998248,-0.05001752,0.32268905,0.37270657,238062.6545,423201.2331
+11,36.40574436,127.4239881,41.52476883,25.446,66.97076883,-0.41923117,-0.0455246,0.37370657,238031.6514,423150.6845
+12,36.40563471,127.4239152,41.60871506,25.446,67.05471506,-0.33528494,0.03842163,0.37370657,238025.1657,423138.4882
+13,36.40561128,127.4238996,41.4198494,25.446,66.8658494,-0.5241506,-0.15044403,0.37370657,238023.7777,423135.8821
+14,36.40558469,127.4238819,41.55545425,25.446,67.00145425,-0.38854575,-0.01483918,0.37370657,238022.203,423132.9245
+15,36.40542242,127.4237564,41.48543549,25.445,66.93043549,-0.45956451,-0.08485794,0.37470657,238011.0246,423114.8684
+16,36.40506118,127.4234769,41.29170227,25.445,66.73670227,-0.65329773,-0.27859116,0.37470657,237986.1291,423074.6725
+17,36.40473806,127.4232272,41.03116226,25.444,66.47516226,-0.91483774,-0.53913117,0.37570657,237963.888,423038.7185
+18,36.40465234,127.4231624,41.08422089,25.444,66.52822089,-0.86177911,-0.48607254,0.37570657,237958.117,423029.1809
+19,36.40431786,127.4229004,40.83958054,25.443,66.28258054,-1.10741946,-0.73071289,0.37670657,237934.7778,422991.9615
+20,36.40387141,127.4225525,40.823349,25.442,66.265349,-1.124651,-0.74694443,0.37770657,237903.7873,422942.2835
+21,36.40368288,127.4224317,40.7629776,25.442,66.2049776,-1.1850224,-0.80731583,0.37770657,237893.0428,422921.3154
+22,36.40366536,127.4224204,40.95827866,25.442,66.40027866,-0.98972134,-0.61201477,0.37770657,237892.0377,422919.3668
+23,36.40361103,127.4223783,40.73271179,25.441,66.17371179,-1.21628821,-0.83758164,0.37870657,237888.2876,422913.3214
+24,36.40277717,127.4217311,41.59788513,25.439,67.03688513,-0.35311487,0.0275917,0.38070657,237830.6362,422820.5363
+25,36.40259122,127.4215646,41.60122681,25.439,67.04022681,-0.34977319,0.03093338,0.38070657,237815.7906,422799.8367
+26,36.4022992,127.4213032,41.19711685,25.438,66.63511685,-0.75488315,-0.37317658,0.38170657,237792.4834,422767.3297
+27,36.40222619,127.4212379,41.42190933,25.438,66.85990933,-0.53009067,-0.1483841,0.38170657,237786.6611,422759.2024
+28,36.40196761,127.4210064,40.89447021,25.437,66.33147021,-1.05852979,-0.67582322,0.38270657,237766.0196,422730.4179
+29,36.4011264,127.4203562,40.86409378,25.435,66.29909378,-1.09090622,-0.70619965,0.38470657,237708.1001,422636.8169
+30,36.40071907,127.420067,40.8819313,25.434,66.3159313,-1.0740687,-0.68836213,0.38570657,237682.3539,422591.5036
+31,36.40059149,127.4199515,40.91270447,25.434,66.34670447,-1.04329553,-0.65758896,0.38570657,237672.0545,422577.3013
+32,36.40051533,127.4198825,40.8580513,25.434,66.2920513,-1.0979487,-0.71224213,0.38570657,237665.9015,422568.8231
+33,36.40033894,127.4197646,40.81824493,25.433,66.25124493,-1.13875507,-0.7520485,0.38670657,237655.4102,422549.2036
+34,36.40033238,127.4197602,40.81824493,25.433,66.25124493,-1.13875507,-0.7520485,0.38670657,237655.0187,422548.474
+35,36.40011674,127.4196154,40.86355209,25.433,66.29655209,-1.09344791,-0.70674134,0.38670657,237642.1332,422524.4885
+36,36.39993958,127.4195258,40.91473389,25.433,66.34773389,-1.04226611,-0.65555954,0.38670657,237634.1809,422504.7946
+37,36.39971165,127.4193717,41.06347656,25.433,66.49647656,-0.89352344,-0.50681687,0.38670657,237620.4669,422479.4418
+38,36.39970146,127.4193606,40.94778442,25.433,66.38078442,-1.00921558,-0.62250901,0.38670657,237619.476,422478.3067
+39,36.39948404,127.4191978,38.53098297,25.432,63.96298297,-3.42701703,-3.03931046,0.38770657,237604.9765,422454.1168
+40,36.39940682,127.4191465,36.66693878,25.432,62.09893878,-5.29106122,-4.90335465,0.38770657,237600.4117,422445.5279
+41,36.39912965,127.4189625,41.26615143,25.432,66.69815143,-0.69184857,-0.304142,0.38770657,237584.0389,422414.6994
+42,36.39894254,127.4188196,41.63571167,25.431,67.06671167,-0.32328833,0.06541824,0.38870657,237571.3097,422393.8807
+43,36.39849481,127.4184778,42.18122101,25.431,67.61222101,0.22222101,0.61092758,0.38870657,237540.8628,422344.0644
+44,36.39797347,127.4180797,42.58108521,25.43,68.01108521,0.62108521,1.01079178,0.38970657,237505.4003,422286.058
+45,36.3970081,127.4172903,43.31628799,25.427,68.74328799,1.35328799,1.74599456,0.39270657,237435.0469,422178.6272
+46,36.39618146,127.4166454,43.1414299,25.426,68.5674299,1.1774299,1.57113647,0.39370657,237377.5885,422086.6474
+47,36.39570053,127.4163161,42.93940353,25.426,68.36540353,0.97540353,1.3691101,0.39370657,237348.2767,422033.1525
+48,36.39552093,127.4162071,43.17940521,25.426,68.60540521,1.21540521,1.60911178,0.39370657,237338.584,422013.1806
+49,36.39498443,127.4159034,43.6729126,25.426,69.0989126,1.7089126,2.10261917,0.39370657,237311.5949,421953.5293
+50,36.39486176,127.415852,43.27485657,25.426,68.70085657,1.31085657,1.70456314,0.39370657,237307.0423,421939.8971
+51,36.39422826,127.415751,47.34189224,25.426,72.76789224,5.37789224,5.77159881,0.39370657,237298.2839,421869.5604
+52,36.39416952,127.4157416,47.3711853,25.427,72.7981853,5.4081853,5.80089187,0.39270657,237297.4687,421863.0385
+53,36.39399658,127.4156931,47.49637604,25.427,72.92337604,5.53337604,5.92608261,0.39270657,237293.2002,421843.8291
+54,36.39340395,127.4156253,47.80435562,25.427,73.23135562,5.84135562,6.23406219,0.39270657,237287.4006,421778.0405
+55,36.39313563,127.4155946,47.86821365,25.428,73.29621365,5.90621365,6.29792022,0.39170657,237284.7746,421748.2539
+56,36.39056499,127.4153107,49.17352295,25.431,74.60452295,7.21452295,7.60322952,0.38870657,237260.5313,421462.8877
+57,36.39036762,127.415278,48.63658905,25.431,74.06758905,6.67758905,7.06629562,0.38870657,237257.6917,421440.9735
+58,36.38926813,127.4151777,49.91009521,25.433,75.34309521,7.95309521,8.33980178,0.38670657,237249.2176,421318.9276
+59,36.38915052,127.4151608,50.16888809,25.433,75.60188809,8.21188809,8.59859466,0.38670657,237247.7574,421305.8702
+60,36.38863739,127.4151122,50.6071434,25.434,76.0411434,8.6511434,9.03684997,0.38570657,237243.6418,421248.9109
+61,36.38740675,127.4150429,50.97354889,25.436,76.40954889,9.01954889,9.40325546,0.38370657,237238.0111,421112.3237
+62,36.38691536,127.4150766,52.17303467,25.437,77.61003467,10.22003467,10.60274124,0.38270657,237241.269,421057.8086
+63,36.3860389,127.4151238,51.46143341,25.438,76.89943341,9.50943341,9.89113998,0.38170657,237245.9219,420960.5686
+64,36.38526003,127.4152376,50.78461838,25.44,76.22461838,8.83461838,9.21432495,0.37970657,237256.504,420874.1836
+65,36.38505349,127.4152947,59.9564476,25.441,85.3974476,18.0074476,18.38615417,0.37870657,237261.7258,420851.2865
+66,36.38419502,127.4155889,85.33042908,25.443,110.7734291,43.38342908,43.76013565,0.37670657,237288.5325,420756.1382
+67,36.38366997,127.4157498,72.45119476,25.444,97.89519476,30.50519476,30.88090133,0.37570657,237303.22,420697.9371
+68,36.38339045,127.4159008,64.00402832,25.445,89.44902832,22.05902832,22.43373489,0.37470657,237316.9021,420666.9779
+69,36.38314509,127.4160974,58.09113693,25.446,83.53713693,16.14713693,16.5208435,0.37370657,237334.6596,420639.827
+70,36.38224378,127.4172973,58.28813934,25.452,83.74013934,16.35013934,16.71784591,0.36770657,237442.7542,420540.2758
+71,36.38170252,127.4183588,59.54457474,25.457,85.00157474,17.61157474,17.97428131,0.36270657,237538.2598,420480.6259
+72,36.38104417,127.4199764,59.53992844,25.466,85.00592844,17.61592844,17.96963501,0.35370657,237683.7213,420408.2006
+73,36.38096833,127.4201627,59.42315292,25.467,84.89015292,17.50015292,17.85285949,0.35270657,237700.4744,420399.8576
+74,36.38087942,127.4203608,58.8523941,25.468,84.3203941,16.9303941,17.28210067,0.35170657,237718.2926,420390.0688
+75,36.38074153,127.4205989,58.97137451,25.469,84.44037451,17.05037451,17.40108108,0.35070657,237739.7237,420374.8606
+76,36.38024182,127.4214679,56.49552536,25.473,81.96852536,14.57852536,14.92523193,0.34670657,237817.9401,420319.7492
+77,36.38022753,127.4214818,56.49552536,25.474,81.96952536,14.57952536,14.92523193,0.34570657,237819.1943,420318.1689
+78,36.38012786,127.4216204,50.14168167,25.474,75.61568167,8.22568167,8.57138824,0.34570657,237831.6791,420307.1631
+79,36.38006521,127.4216876,50.59542847,25.475,76.07042847,8.68042847,9.02513504,0.34470657,237837.7393,420300.2373
+80,36.38006399,127.4216889,50.59542847,25.475,76.07042847,8.68042847,9.02513504,0.34470657,237837.8565,420300.1025
+81,36.37988367,127.4219199,57.89454651,25.476,83.37054651,15.98054651,16.32425308,0.34370657,237858.6715,420280.1834
+82,36.3798252,127.4219776,57.80186081,25.476,83.27786081,15.88786081,16.23156738,0.34370657,237863.8773,420273.7178
+83,36.37978972,127.4220173,57.65145874,25.476,83.12745874,15.73745874,16.08116531,0.34370657,237867.4567,420269.7962
+84,36.37962201,127.4222052,54.06899643,25.477,79.54599643,12.15599643,12.498703,0.34270657,237884.3984,420251.2597
+85,36.37956504,127.4222487,48.96678162,25.478,74.44478162,7.05478162,7.39648819,0.34170657,237888.3293,420244.9549
+86,36.37938553,127.4224278,48.86730576,25.479,74.34630576,6.95630576,7.29701233,0.34070657,237904.4871,420225.1055
+87,36.37932247,127.4224717,53.37725067,25.479,78.85625067,11.46625067,11.80695724,0.34070657,237908.4569,420218.1252
+88,36.37916017,127.4226259,56.55082321,25.48,82.03082321,14.64082321,14.98052978,0.33970657,237922.3721,420200.1758
+89,36.37902074,127.4227186,56.09943008,25.48,81.57943008,14.18943008,14.52913665,0.33970657,237930.7579,420184.74
+90,36.3787154,127.4229403,56.83562851,25.482,82.31762851,14.92762851,15.26533508,0.33770657,237950.7996,420150.9445
+91,36.37839053,127.4231056,56.23346329,25.483,81.71646329,14.32646329,14.66316986,0.33670657,237965.7901,420114.9596
+92,36.37794511,127.423297,55.92332077,25.484,81.40732077,14.01732077,14.35302734,0.33570657,237983.1813,420065.6079
+93,36.37764983,127.4233969,51.13707352,25.484,76.62107352,9.23107352,9.56678009,0.33570657,237992.2892,420032.8809
+94,36.37761956,127.4234117,50.7040329,25.485,76.1890329,8.7990329,9.13373947,0.33470657,237993.632,420029.5278
+95,36.37740043,127.4234464,53.27496719,25.485,78.75996719,11.36996719,11.70467376,0.33470657,237996.8523,420005.2252
+96,36.37735955,127.4234526,55.02401352,25.485,80.50901352,13.11901352,13.45372009,0.33470657,237997.4285,420000.6913
+97,36.37689308,127.4235306,54.34658813,25.486,79.83258813,12.44258813,12.7762947,0.33370657,238004.6546,419948.9593
+98,36.37680543,127.423525,54.22592926,25.486,79.71192926,12.32192926,12.65563583,0.33370657,238004.1948,419939.2308
+99,36.37669421,127.4235331,54.29218292,25.486,79.77818292,12.38818292,12.72188949,0.33370657,238004.9757,419926.8923
+100,36.37638873,127.4235552,54.00867844,25.486,79.49467844,12.10467844,12.43838501,0.33370657,238007.1074,419893.0028
+101,36.37628055,127.423563,54.09650803,25.486,79.58250803,12.19250803,12.5262146,0.33370657,238007.86,419881.0015
+102,36.37616516,127.4235585,54.11535645,25.486,79.60135645,12.21135645,12.54506302,0.33370657,238007.5123,419868.1952
+103,36.37610291,127.4235459,54.13011551,25.486,79.61611551,12.22611551,12.55982208,0.33370657,238006.412,419861.2826
+104,36.37586476,127.4235339,53.88108063,25.486,79.36708063,11.97708063,12.3107872,0.33370657,238005.451,419834.8511
+105,36.37579755,127.423535,53.98939514,25.486,79.47539514,12.08539514,12.41910171,0.33370657,238005.5824,419827.3935
+106,36.37573713,127.4235288,54.19614792,25.486,79.68214792,12.29214792,12.62585449,0.33370657,238005.0555,419820.6864
+107,36.37571155,127.423522,53.85792923,25.486,79.34392923,11.95392923,12.2876358,0.33370657,238004.4577,419817.8452
+108,36.37549001,127.423501,54.22356796,25.486,79.70956796,12.31956796,12.65327453,0.33370657,238002.681,419793.2533
+109,36.37541847,127.4234946,54.19550323,25.486,79.68150323,12.29150323,12.6252098,0.33370657,238002.1415,419785.3122
+110,36.37538552,127.4234902,54.16474533,25.486,79.65074533,12.26074533,12.5944519,0.33370657,238001.7627,419781.6541
+111,36.37536502,127.4234877,54.13046646,25.486,79.61646646,12.22646646,12.56017303,0.33370657,238001.5484,419779.3783
+112,36.37532988,127.4234841,54.13046646,25.486,79.61646646,12.22646646,12.56017303,0.33370657,238001.2424,419775.4775
+113,36.37514465,127.423456,54.04568863,25.486,79.53168863,12.14168863,12.4753952,0.33370657,237998.811,419754.9121
+114,36.37506757,127.4234428,54.01882553,25.486,79.50482553,12.11482553,12.4485321,0.33370657,237997.6639,419746.3536
+115,36.37503558,127.4234333,53.98856735,25.486,79.47456735,12.08456735,12.41827392,0.33370657,237996.827,419742.8
+116,36.37500016,127.4234283,53.96323395,25.486,79.44923395,12.05923395,12.39294052,0.33370657,237996.3956,419738.8676
+117,36.37496874,127.4234238,53.96323395,25.486,79.44923395,12.05923395,12.39294052,0.33370657,237996.007,419735.3792
+118,36.37495222,127.4234191,53.93666458,25.486,79.42266458,12.03266458,12.36637115,0.33370657,237995.5933,419733.5442
+119,36.37483107,127.4233925,53.77856445,25.486,79.26456445,11.87456445,12.20827102,0.33370657,237993.2653,419720.0901
+120,36.37472913,127.4233604,53.7809639,25.486,79.2669639,11.8769639,12.21067047,0.33370657,237990.4343,419708.7655
+121,36.37419181,127.4232687,53.59219742,25.486,79.07819742,11.68819742,12.02190399,0.33370657,237982.4668,419649.1048
+122,36.37418735,127.4232673,53.59219742,25.486,79.07819742,11.68819742,12.02190399,0.33370657,237982.3433,419648.6093
+123,36.37409419,127.4232387,53.48587036,25.486,78.97187036,11.58187036,11.91557693,0.33370657,237979.8221,419638.2604
+124,36.37396916,127.4232126,54.04447937,25.486,79.53047937,12.14047937,12.47418594,0.33370657,237977.5408,419624.3759
+125,36.37389533,127.4231911,56.30555725,25.486,81.79155725,14.40155725,14.73526382,0.33370657,237975.6473,419616.1748
+126,36.37337734,127.4230781,55.09450912,25.486,80.58050912,13.19050912,13.52421569,0.33370657,237965.7588,419558.6507
+127,36.37329854,127.4230637,54.96466064,25.486,80.45066064,13.06066064,13.39436721,0.33370657,237964.5048,419549.9008
+128,36.37294774,127.4229921,45.18955231,25.485,70.67455231,3.28455231,3.61925888,0.33470657,237958.2501,419510.9455
+129,36.37284214,127.4229663,53.25004959,25.485,78.73504959,11.34504959,11.67975616,0.33470657,237955.9861,419499.2173
+130,36.37266553,127.4229029,53.61932373,25.485,79.10432373,11.71432373,12.0490303,0.33470657,237950.3825,419479.5945
+131,36.37238859,127.4228433,53.58890533,25.485,79.07390533,11.68390533,12.0186119,0.33470657,237945.1686,419448.84
+132,36.37221666,127.4228004,53.70202637,25.485,79.18702637,11.79702637,12.13173294,0.33470657,237941.4023,419429.7446
+133,36.37189658,127.4227334,53.49817657,25.485,78.98317657,11.59317657,11.92788314,0.33470657,237935.5452,419394.2
+134,36.37172442,127.4226916,53.52459335,25.485,79.00959335,11.61959335,11.95429992,0.33470657,237931.8777,419375.0796
+135,36.37152283,127.4226431,53.41849518,25.485,78.90349518,11.51349518,11.84820175,0.33470657,237927.6232,419352.6907
+136,36.37146718,127.4226286,53.41088104,25.484,78.89488104,11.50488104,11.84058761,0.33570657,237926.349,419346.5097
+137,36.37134071,127.4225957,53.45143509,25.484,78.93543509,11.54543509,11.88114166,0.33570657,237923.4579,419332.4629
+138,36.37132619,127.4225919,53.45143509,25.484,78.93543509,11.54543509,11.88114166,0.33570657,237923.124,419330.8501
+139,36.37114463,127.422546,53.31612778,25.484,78.80012778,11.41012778,11.74583435,0.33570657,237919.093,419310.685
+140,36.37088129,127.4224792,53.46446228,25.484,78.94846228,11.55846228,11.89416885,0.33570657,237913.2262,419281.4368
+141,36.3708327,127.4224669,53.47537994,25.484,78.95937994,11.56937994,11.90508651,0.33570657,237912.1459,419276.0401
+142,36.37075141,127.4224429,53.46264648,25.484,78.94664648,11.55664648,11.89235305,0.33570657,237910.0316,419267.0102
+143,36.37056365,127.4223929,53.47391891,25.484,78.95791891,11.56791891,11.90362548,0.33570657,237905.6357,419246.1554
+144,36.3703695,127.4223379,53.34194183,25.484,78.82594183,11.43594183,11.7716484,0.33570657,237900.7941,419224.5896
+145,36.37024013,127.4223006,53.54463196,25.484,79.02863196,11.63863196,11.97433853,0.33570657,237897.5095,419210.2192
+146,36.37002104,127.4222041,53.2318573,25.483,78.7148573,11.3248573,11.66156387,0.33670657,237888.9557,419185.8697
+147,36.36998007,127.4221915,53.21572113,25.483,78.69872113,11.30872113,11.6454277,0.33670657,237887.8449,419181.3184
+148,36.36986554,127.4221565,53.491539,25.483,78.974539,11.584539,11.92124557,0.33670657,237884.7594,419168.5957
+149,36.36964157,127.4220867,53.58861542,25.483,79.07161542,11.68161542,12.01832199,0.33670657,237878.6041,419143.7151
+150,36.36963046,127.422083,53.58861542,25.483,79.07161542,11.68161542,12.01832199,0.33670657,237878.2774,419142.4808
+151,36.3695557,127.4220581,53.59433365,25.483,79.07733365,11.68733365,12.02404022,0.33670657,237876.0791,419134.1752
+152,36.36954338,127.4220544,53.59433365,25.483,79.07733365,11.68733365,12.02404022,0.33670657,237875.753,419132.8066
+153,36.36948571,127.422037,53.56835175,25.483,79.05135175,11.66135175,11.99805832,0.33670657,237874.2194,419126.4003
+154,36.36926853,127.4219859,53.58152771,25.483,79.06452771,11.67452771,12.01123428,0.33670657,237869.7389,419102.2805
+155,36.36923386,127.4219776,53.60071564,25.483,79.08371564,11.69371564,12.03042221,0.33670657,237869.0108,419098.4301
+156,36.36898828,127.421916,53.26034164,25.483,78.74334164,11.35334164,11.69004821,0.33670657,237863.6017,419071.1547
+157,36.36889178,127.4218858,53.27832031,25.482,78.76032031,11.37032031,11.70802688,0.33770657,237860.9382,419060.4346
+158,36.36863091,127.4218064,53.42208862,25.482,78.90408862,11.51408862,11.85179519,0.33770657,237853.939,419031.4556
+159,36.36852491,127.4217728,53.25052261,25.482,78.73252261,11.34252261,11.68022918,0.33770657,237850.975,419019.6799
+160,36.368275,127.4216997,53.42486954,25.482,78.90686954,11.51686954,11.85457611,0.33770657,237844.5358,418991.9196
+161,36.36811583,127.4216423,53.20927429,25.482,78.69127429,11.30127429,11.63898086,0.33770657,237839.4616,418974.2345
+162,36.36809035,127.4216331,53.20927429,25.482,78.69127429,11.30127429,11.63898086,0.33770657,237838.6483,418971.4035
+163,36.36794963,127.4215823,53.27620697,25.482,78.75820697,11.36820697,11.70591354,0.33770657,237834.1575,418955.7684
+164,36.36785171,127.421547,53.64022446,25.482,79.12222446,11.73222446,12.06993103,0.33770657,237831.0369,418944.8887
+165,36.36781128,127.4215299,53.65616226,25.482,79.13816226,11.74816226,12.08586883,0.33770657,237829.5219,418940.3956
+166,36.36773201,127.4215061,53.46281433,25.482,78.94481433,11.55481433,11.8925209,0.33770657,237827.4244,418931.59
+167,36.36744901,127.4214266,53.37786484,25.481,78.85886484,11.46886484,11.80757141,0.33870657,237820.4267,418900.1553
+168,36.3673742,127.4214036,53.50073242,25.481,78.98173242,11.59173242,11.93043899,0.33870657,237818.3988,418891.8448
+169,36.36727257,127.4213725,53.53074646,25.481,79.01174646,11.62174646,11.96045303,0.33870657,237815.6569,418880.5551
+170,36.36697951,127.4212821,53.46721268,25.481,78.94821268,11.55821268,11.89691925,0.33870657,237807.6858,418847.9998
+171,36.36678367,127.421224,53.54465866,25.481,79.02565866,11.63565866,11.97436523,0.33870657,237802.5664,418826.2454
+172,36.36649705,127.421134,53.74835205,25.481,79.22935205,11.83935205,12.17805862,0.33870657,237794.6279,418794.4049
+173,36.36622746,127.4210474,53.50355148,25.481,78.98455148,11.59455148,11.93325805,0.33870657,237786.9863,418764.4555
+174,36.36617757,127.4210351,53.47144699,25.481,78.95244699,11.56244699,11.90115356,0.33870657,237785.9066,418758.9146
+175,36.36599476,127.4209757,53.389328,25.481,78.870328,11.480328,11.81903457,0.33870657,237780.6641,418738.6055
+176,36.36592042,127.4209598,53.53152847,25.481,79.01252847,11.62252847,11.96123504,0.33870657,237779.273,418730.35
+177,36.36557559,127.4208556,53.51815033,25.481,78.99915033,11.60915033,11.9478569,0.33870657,237770.0882,418692.0447
+178,36.36543876,127.4208146,53.28448486,25.481,78.76548486,11.37548486,11.71419143,0.33870657,237766.4747,418676.8451
+179,36.36538894,127.420799,53.44216156,25.481,78.92316156,11.53316156,11.87186813,0.33870657,237765.0987,418671.3106
+180,36.36528417,127.4207745,53.3886528,25.481,78.8696528,11.4796528,11.81835937,0.33870657,237762.9505,418659.675
+181,36.36510399,127.4207183,53.25595474,25.481,78.73695474,11.34695474,11.68566131,0.33870657,237757.9938,418639.6591
+182,36.36499276,127.4206764,53.24317551,25.481,78.72417551,11.33417551,11.67288208,0.33870657,237754.2871,418627.2999
+183,36.36484026,127.4206282,53.37047958,25.481,78.85147958,11.46147958,11.80018615,0.33870657,237750.035,418610.3587
+184,36.36475767,127.4205959,53.42734146,25.481,78.90834146,11.51834146,11.85704803,0.33870657,237747.1761,418601.1813
+185,36.36418056,127.4203704,53.45589828,25.48,78.93589828,11.54589828,11.88560485,0.33970657,237727.2166,418537.0533
+186,36.36402718,127.4203104,53.42592239,25.48,78.90592239,11.51592239,11.85562896,0.33970657,237721.9058,418520.0098
+187,36.3637957,127.4202041,53.32323456,25.48,78.80323456,11.41323456,11.75294113,0.33970657,237712.4772,418494.2817
+188,36.36369089,127.420156,53.40998459,25.48,78.88998459,11.49998459,11.83969116,0.33970657,237708.2109,418482.6325
+189,36.36309743,127.4198833,53.41979218,25.479,78.89879218,11.50879218,11.84949875,0.34070657,237684.0226,418416.6719
+190,36.36212117,127.4194139,53.68809891,25.478,79.16609891,11.77609891,12.11780548,0.34170657,237642.3645,418308.1567
+191,36.36157235,127.4191454,53.42456818,25.478,78.90256818,11.51256818,11.85427475,0.34170657,237618.5306,418247.1514
+192,36.36142831,127.4190749,53.41180038,25.477,78.88880038,11.49880038,11.84150695,0.34270657,237612.2725,418231.1404
+193,36.36055967,127.4187004,53.5123024,25.477,78.9893024,11.5993024,11.94200897,0.34270657,237579.0783,418134.6046
+194,36.36037084,127.4186082,53.36859131,25.476,78.84459131,11.45459131,11.79829788,0.34370657,237570.8939,418113.615
+195,36.36011013,127.4184809,53.29519272,25.476,78.77119272,11.38119272,11.72489929,0.34370657,237559.5937,418084.6354
+196,36.36007387,127.4184644,53.29519272,25.476,78.77119272,11.38119272,11.72489929,0.34370657,237558.1302,418080.6053
+197,36.35847655,127.4177903,46.75944519,25.475,72.23444519,4.84444519,5.18915176,0.34470657,237498.3941,417903.0945
+198,36.35821646,127.4176806,51.53353119,25.474,77.00753119,9.61753119,9.96323776,0.34570657,237488.6728,417874.1906
+199,36.358179,127.4176583,51.53353119,25.474,77.00753119,9.61753119,9.96323776,0.34570657,237486.6892,417870.0251
+200,36.35781773,127.417527,51.11881256,25.474,76.59281256,9.20281256,9.54851913,0.34570657,237475.0776,417829.8853
+201,36.35750462,127.4174362,50.66068649,25.474,76.13468649,8.74468649,9.09039306,0.34570657,237467.0778,417795.1054
+202,36.35745961,127.4174231,50.5848732,25.474,76.0588732,8.6688732,9.01457977,0.34570657,237465.9236,417790.1057
+203,36.35715403,127.4173535,50.41460037,25.474,75.88860037,8.49860037,8.84430694,0.34570657,237459.823,417756.1696
+204,36.35680229,127.4172756,49.77857971,25.474,75.25257971,7.86257971,8.20828628,0.34570657,237452.9996,417717.1081
+205,36.35668056,127.4172486,49.61360931,25.474,75.08760931,7.69760931,8.04331588,0.34570657,237450.6344,417703.5896
+206,36.35645932,127.4172542,49.47008896,25.475,74.94508896,7.55508896,7.89979553,0.34470657,237451.2431,417679.0416
+207,36.3563789,127.4172551,49.41373444,25.475,74.88873444,7.49873444,7.84344101,0.34470657,237451.3624,417670.118
+208,36.35601512,127.4172589,49.23891449,25.475,74.71391449,7.32391449,7.66862106,0.34470657,237451.8777,417629.7521
+209,36.3556022,127.4172727,48.82962036,25.476,74.30562036,6.91562036,7.25932693,0.34370657,237453.3142,417583.9371
+210,36.35511251,127.4173598,47.97132111,25.477,73.44832111,6.05832111,6.40102768,0.34270657,237461.3668,417529.6317
+211,36.35454842,127.4174923,47.38679123,25.478,72.86479123,5.47479123,5.8164978,0.34170657,237473.5301,417467.088
+212,36.35426029,127.4175824,47.28036118,25.479,72.75936118,5.36936118,5.71006775,0.34070657,237481.7556,417435.1502
+213,36.35407392,127.4176626,47.15336227,25.479,72.63236227,5.24236227,5.58306884,0.34070657,237489.0436,417414.5005
+214,36.35379022,127.4178076,46.89318466,25.48,72.37318466,4.98318466,5.32289123,0.33970657,237502.1949,417383.0755
+215,36.3534406,127.4180014,47.07096863,25.482,72.55296863,5.16296863,5.5006752,0.33770657,237519.7581,417344.3546
+216,36.35305816,127.4182339,46.76593781,25.483,72.24893781,4.85893781,5.19564438,0.33670657,237540.811,417302.0069
+217,36.35244835,127.4186406,46.82806015,25.486,72.31406015,4.92406015,5.25776672,0.33370657,237577.6098,417234.4965
+218,36.35188261,127.419022,47.00273514,25.489,72.49173514,5.10173514,5.43244171,0.33070657,237612.117,417171.8667
+219,36.35088673,127.4197025,47.42319489,25.494,72.91719489,5.52719489,5.85290146,0.32570657,237673.68,417061.6225
+220,36.35048928,127.4199994,47.70178986,25.496,73.19778986,5.80778986,6.13149643,0.32370657,237700.5223,417017.6346
+221,36.35001437,127.4203669,48.15553284,25.498,73.65353284,6.26353284,6.58523941,0.32170657,237733.7397,416965.079
+222,36.34968947,127.4206222,48.69305801,25.5,74.19305801,6.80305801,7.12276458,0.31970657,237756.8134,416929.1257
+223,36.3494895,127.4207875,48.82459641,25.501,74.32559641,6.93559641,7.25430298,0.31870657,237771.7481,416907.0003
diff --git a/pythonsource/streamlined_tuner.spec b/pythonsource/streamlined_tuner.spec
new file mode 100644
index 0000000..533e4e4
--- /dev/null
+++ b/pythonsource/streamlined_tuner.spec
@@ -0,0 +1,45 @@
+# -*- mode: python ; coding: utf-8 -*-
+from PyInstaller.utils.hooks import collect_all
+
+datas = []
+binaries = []
+hiddenimports = []
+tmp_ret = collect_all('pyproj')
+datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
+
+
+a = Analysis(
+ ['advanced_tuner_v2.py'],
+ pathex=[],
+ binaries=binaries,
+ datas=datas,
+ hiddenimports=hiddenimports,
+ hookspath=[],
+ hooksconfig={},
+ runtime_hooks=[],
+ excludes=[],
+ noarchive=False,
+ optimize=0,
+)
+pyz = PYZ(a.pure)
+
+exe = EXE(
+ pyz,
+ a.scripts,
+ a.binaries,
+ a.datas,
+ [],
+ name='streamlined_tuner',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ upx_exclude=[],
+ runtime_tmpdir=None,
+ console=False,
+ disable_windowed_traceback=False,
+ argv_emulation=False,
+ target_arch=None,
+ codesign_identity=None,
+ entitlements_file=None,
+)
diff --git a/pythonsource/캡처.png b/pythonsource/캡처.png
new file mode 100644
index 0000000..0470c11
Binary files /dev/null and b/pythonsource/캡처.png differ
diff --git a/storage/baeksong.json b/storage/baeksong.json
new file mode 100644
index 0000000..4f67412
--- /dev/null
+++ b/storage/baeksong.json
@@ -0,0 +1 @@
+{"poi":{"title":"백송 아파트","category":"지장물","lat":36.380154,"lon":127.42062,"z":22.22890515,"type":"poi"},"frames":[{"frame":13328,"time":444.26666666666665,"bearingDiff":2.416515832319874,"elevationDiff":15.419007353837134,"distance":378.8223157131149,"pixelX":0.5327708508378821,"pixelY":0.2097877348126167,"groupSize":10523,"groupStart":13328,"groupEnd":3877},{"frame":372,"time":12.4,"bearingDiff":-0.3950378036713573,"elevationDiff":28.313526733811663,"distance":2466.701205588134,"pixelX":0.49464281393637277,"pixelY":0,"groupSize":1993,"groupStart":372,"groupEnd":254}]}
\ No newline at end of file
diff --git a/storage/baeksong2.json b/storage/baeksong2.json
new file mode 100644
index 0000000..2b4326c
--- /dev/null
+++ b/storage/baeksong2.json
@@ -0,0 +1 @@
+{"poi":{"title":"백송 아파트","category":"지장물","lat":36.380154,"lon":127.42062,"z":22.22890515,"type":"poi"},"frames":[{"frame":13328,"time":444.26666666666665,"bearingDiff":2.416515832319874,"elevationDiff":15.419007353837134,"distance":378.8223157131149,"pixelX":0.5327708508378821,"pixelY":0.2097877348126167,"groupSize":5696,"groupStart":8612,"groupEnd":14315}]}
\ No newline at end of file
diff --git a/storage/geo_result.json b/storage/geo_result.json
new file mode 100644
index 0000000..4613e65
--- /dev/null
+++ b/storage/geo_result.json
@@ -0,0 +1 @@
+{"poi":{"title":"회덕역","category":"역사","lat":36.402299,"lon":127.421303,"z":8.626823852,"type":"poi"},"frames":[{"frame":2999,"time":99.96666666666667,"bearingDiff":-0.9585235927831377,"elevationDiff":0.06681769990423447,"distance":163.52956276077978,"pixelX":0.48700127130823234,"pixelY":0.4987423758482745,"groupSize":1070,"groupStart":2999,"groupEnd":2355}]}
\ No newline at end of file
diff --git a/storage/pois.json b/storage/pois.json
new file mode 100644
index 0000000..f1a7987
--- /dev/null
+++ b/storage/pois.json
@@ -0,0 +1 @@
+[{"title":"한국철도공사대전조차장역","category":"지장물","lat":36.371101,"lon":127.421776,"z":14.93833585,"type":"poi"},{"title":"공업사","category":"지장물","lat":36.380398,"lon":127.422422,"z":17.43774457,"type":"poi"},{"title":"음식점","category":"지장물","lat":36.379428,"lon":127.423479,"z":25.45520444,"type":"poi"},{"title":"교회","category":"지장물","lat":36.378866,"lon":127.423721,"z":22.83119626,"type":"poi"},{"title":"공장","category":"지장물","lat":36.378592,"lon":127.421883,"z":11.92308469,"type":"poi"},{"title":"음식점","category":"지장물","lat":36.377671,"lon":127.422335,"z":12.88381619,"type":"poi"},{"title":"오성우산 대전물류센터","category":"지장물","lat":36.377714,"lon":127.42416,"z":14.40417523,"type":"poi"},{"title":"쌍용더플래티넘네이처아파트","category":"지장물","lat":36.37701,"lon":127.424777,"z":18.89580197,"type":"poi"},{"title":"창원기전","category":"지장물","lat":36.374582,"lon":127.423243,"z":14.899754,"type":"poi"},{"title":"삼표산업 대전공장","category":"지장물","lat":36.372438,"lon":127.423178,"z":14.87806363,"type":"poi"},{"title":"삼표레미콘","category":"지장물","lat":36.372081,"lon":127.423092,"z":14.83134885,"type":"poi"},{"title":"대전캐노픽스","category":"지장물","lat":36.391715,"lon":127.415962,"z":23.5801167,"type":"poi"},{"title":"보명폴딩도어","category":"지장물","lat":36.391248,"lon":127.415945,"z":27.74913449,"type":"poi"},{"title":"삼보목재","category":"지장물","lat":36.39071,"lon":127.414704,"z":2.79518933,"type":"poi"},{"title":"아이엘케이","category":"지장물","lat":36.390094,"lon":127.414781,"z":3.599010894,"type":"poi"},{"title":"대우사료공장","category":"지장물","lat":36.388126,"lon":127.41469,"z":1.855225036,"type":"poi"},{"title":"88자원","category":"지장물","lat":36.381059,"lon":127.420448,"z":21.30201382,"type":"poi"},{"title":"백송 아파트","category":"지장물","lat":36.380154,"lon":127.42062,"z":22.22890515,"type":"poi"},{"title":"회덕화물역","category":"지장물","lat":36.402127,"lon":127.42177,"z":3.29909558,"type":"poi"},{"title":"대덕자원","category":"지장물","lat":36.401742,"lon":127.421464,"z":2.56787152,"type":"poi"},{"title":"대전철거","category":"지장물","lat":36.399513,"lon":127.419798,"z":1.260082671,"type":"poi"},{"title":"경부고속도로","category":"지장물","lat":36.398305,"lon":127.418372,"z":3.734718749,"type":"poi"},{"title":"국도17호선(대전로)","category":"지장물","lat":36.379226,"lon":127.421877,"z":10.2714848,"type":"poi"},{"title":"신대천교(복)","category":"교량","lat":36.399342,"lon":127.419143,"z":2.016098449,"type":"poi"},{"title":"장등천교(상)","category":"교량","lat":36.380092,"lon":127.421508,"z":13.34468503,"type":"poi"},{"title":"장등천교(하)","category":"교량","lat":36.380324,"lon":127.421714,"z":13.66731305,"type":"poi"},{"title":"회덕제1가도교(상)","category":"교량","lat":36.379443,"lon":127.422186,"z":12.39197583,"type":"poi"},{"title":"회덕제1가도교(하)","category":"교량","lat":36.379655,"lon":127.422603,"z":13.37028546,"type":"poi"},{"title":"회덕제1가도교(인상)","category":"교량","lat":36.379602,"lon":127.422495,"z":12.97475476,"type":"poi"},{"title":"회덕천교(상)","category":"교량","lat":36.377442,"lon":127.423126,"z":13.50943036,"type":"poi"},{"title":"회덕천교(하)","category":"교량","lat":36.377617,"lon":127.423975,"z":15.0617146,"type":"poi"},{"title":"회덕천교(상인상)","category":"교량","lat":36.377443,"lon":127.423284,"z":13.51244778,"type":"poi"},{"title":"회덕천교(하인상)","category":"교량","lat":36.377673,"lon":127.423649,"z":14.89475293,"type":"poi"},{"title":"법동가도교(하)","category":"교량","lat":36.373047,"lon":127.423932,"z":9.542900512,"type":"poi"},{"title":"법동가도교(상,인상,고속)","category":"교량","lat":36.373021,"lon":127.422035,"z":8.17662091,"type":"poi"},{"title":"법동가도교(인상)","category":"교량","lat":36.373061,"lon":127.423138,"z":8.746838043,"type":"poi"},{"title":"회덕터널(상)","category":"터널","lat":36.384931,"lon":127.415133,"z":16.18040272,"type":"poi"},{"title":"회덕터널(하)","category":"터널","lat":36.384852,"lon":127.415525,"z":22.58381459,"type":"poi"},{"title":"회덕역","category":"역사","lat":36.402299,"lon":127.421303,"z":8.626823852,"type":"poi"},{"title":"대전조차장역","category":"역사","lat":36.36963,"lon":127.422083,"z":21.01832242,"type":"poi"},{"title":"157K900","category":"측점","lat":36.40296455,"lon":127.4218765,"z":0.023576703,"type":"station"},{"title":"158K000","category":"측점","lat":36.40222619,"lon":127.4212379,"z":-0.148290668,"type":"station"},{"title":"158K100","category":"측점","lat":36.40149981,"lon":127.4206448,"z":-0.756826434,"type":"station"},{"title":"158K200","category":"측점","lat":36.40075303,"lon":127.4200911,"z":-0.707216296,"type":"station"},{"title":"158K300","category":"측점","lat":36.40000028,"lon":127.4195565,"z":-0.678056751,"type":"station"},{"title":"158K400","category":"측점","lat":36.39923934,"lon":127.4190353,"z":-0.312562976,"type":"station"},{"title":"158K500","category":"측점","lat":36.39849457,"lon":127.4184776,"z":0.611021008,"type":"station"},{"title":"158k600","category":"측점","lat":36.39775789,"lon":127.4179034,"z":1.283609357,"type":"station"},{"title":"158k700","category":"측점","lat":36.39703149,"lon":127.4173094,"z":1.284124341,"type":"station"},{"title":"158k800","category":"측점","lat":36.39629528,"lon":127.4167342,"z":1.834588971,"type":"station"},{"title":"158k900","category":"측점","lat":36.39553306,"lon":127.4162145,"z":1.609205212,"type":"station"},{"title":"159k000","category":"측점","lat":36.39472513,"lon":127.4158302,"z":4.270502057,"type":"station"},{"title":"159k100","category":"측점","lat":36.39386389,"lon":127.4156779,"z":6.019655194,"type":"station"},{"title":"159k200","category":"측점","lat":36.39299675,"lon":127.4155792,"z":6.22390553,"type":"station"},{"title":"159k300","category":"측점","lat":36.3921294,"lon":127.4154835,"z":6.181451764,"type":"station"},{"title":"159k400","category":"측점","lat":36.39126205,"lon":127.4153877,"z":6.39105412,"type":"station"},{"title":"159k500","category":"측점","lat":36.39039554,"lon":127.4152826,"z":7.06638905,"type":"station"},{"title":"159k600","category":"측점","lat":36.38952728,"lon":127.4152013,"z":8.676607098,"type":"station"},{"title":"159k700","category":"측점","lat":36.38865941,"lon":127.4151143,"z":8.931806531,"type":"station"},{"title":"159k800","category":"측점","lat":36.38778955,"lon":127.4150644,"z":9.882272687,"type":"station"},{"title":"159k900","category":"측점","lat":36.3869199,"lon":127.4150763,"z":10.60283467,"type":"station"},{"title":"160k000","category":"측점","lat":36.38604992,"lon":127.4151232,"z":9.891233411,"type":"station"},{"title":"160k100","category":"측점","lat":36.38518637,"lon":127.4152579,"z":10.30196568,"type":"station"},{"title":"160k200","category":"측점","lat":36.38434553,"lon":127.4155373,"z":38.92352864,"type":"station"},{"title":"160k300","category":"측점","lat":36.3835108,"lon":127.4158358,"z":32.04822346,"type":"station"},{"title":"160k400","category":"측점","lat":36.38284078,"lon":127.4165025,"z":15.85750004,"type":"station"},{"title":"160k500","category":"측점","lat":36.38224812,"lon":127.4172915,"z":16.71793934,"type":"station"},{"title":"160k600","category":"측점","lat":36.3817827,"lon":127.4182016,"z":17.92084691,"type":"station"},{"title":"160k700","category":"측점","lat":36.38137859,"lon":127.4191547,"z":17.75181004,"type":"station"},{"title":"160k800","category":"측점","lat":36.38098707,"lon":127.4201167,"z":17.63405415,"type":"station"},{"title":"160k900","category":"측점","lat":36.38050443,"lon":127.4210112,"z":16.61579701,"type":"station"},{"title":"161k000","category":"측점","lat":36.37994943,"lon":127.4218357,"z":15.94836613,"type":"station"},{"title":"161k100","category":"측점","lat":36.37927713,"lon":127.4225148,"z":14.58936116,"type":"station"},{"title":"161k200","category":"측점","lat":36.37852031,"lon":127.4230395,"z":14.00062367,"type":"station"},{"title":"161k300","category":"측점","lat":36.37769537,"lon":127.4233815,"z":10.50074574,"type":"station"},{"title":"161k400","category":"측점","lat":36.37683495,"lon":127.4235269,"z":12.68091389,"type":"station"},{"title":"161k500","category":"측점","lat":36.37596609,"lon":127.423539,"z":12.3589153,"type":"station"},{"title":"161k600","category":"측점","lat":36.37509924,"lon":127.4234482,"z":12.44862553,"type":"station"},{"title":"161k700","category":"측점","lat":36.3742403,"lon":127.423277,"z":12.05753514,"type":"station"},{"title":"161k800","category":"측점","lat":36.37338461,"lon":127.4230796,"z":13.52430912,"type":"station"},{"title":"161k900","category":"측점","lat":36.37253087,"lon":127.4228739,"z":12.0263538,"type":"station"},{"title":"162k000","category":"측점","lat":36.37167446,"lon":127.4226795,"z":11.82195851,"type":"station"},{"title":"162k100","category":"측점","lat":36.37082138,"lon":127.4224635,"z":11.91039082,"type":"station"},{"title":"162k200","category":"측점","lat":36.36998007,"lon":127.4221915,"z":11.64552113,"type":"station"},{"title":"162k300","category":"측점","lat":36.36909361,"lon":127.4219424,"z":11.83502003,"type":"station"}]
\ No newline at end of file