chore(plan): 10-10 조사 AH(거리이정표)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LLCk2y5xE8YGVgjbTntWsY
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# 조사 AH — B08 거리이정표 메인 탭 · 경로 하위 탭 · 다음(카카오) 지도 (120) (10-10 · 읽기 전용 조사 에이전트)
|
||||
|
||||
약칭: PG `B08_Quantity/B08_Quantity_UI_Page.ts` · OP `B08_Quantity/B08_Quantity_UI_Options.ts` · TB `B09_Estimation/B09_Estimation_UI_TabBar.ts` · BI `B09_Estimation/B09_Estimation_Bill_Items.py` · SG `B09_Estimation/B09_Estimation_Sangeun.py` · RG `common_util/common_util_route_geometry.py` · CRS `common_util/common_util_crs.py` · MAP `B01_Dashboard/B01_Dashboard_Map.py` · L10 `resources/master_data/로직_산림품셈_10장_자재․장비_운반.json` · 견본 = `resources/knowledge/original/실무문서/01.산불거창(거창북상병곡)/01.내역서/…내역+수량.xlsx`(병곡리 968-31 견본의 원본 · 「거리이정표」 시트 A2:AI30)
|
||||
|
||||
## 1. 한눈 결론
|
||||
|
||||
1. B08 탭은 공용 탭 양식 없이 페이지마다 `createButton` 줄로 만듦(PG:30-35 · 118-134). 메인 탭 하나 = 배열에 한 줄 + `renderTab` 가지 한 줄 + 글자 키 하나. 사용자가 늘리고 줄이는 하위 탭 선례는 프로그램 어디에도 없음 — 새로 만듦.
|
||||
2. 거리 km · 도로 구분(포장 · 비포장)을 받는 칸은 프로그램에 없음. B09 운반 줄 6개는 「운반거리 원천 없음」으로 빈칸(BI:21 · 50-57), B09 산근은 운반 산근을 만들지 않음(SG:22). 거리이정표가 그 원천 자리.
|
||||
3. 시점 좌표 = 설계 노선 CSV 첫 점(프로젝트 작업 좌표계 · m). 중점 = 측점 거리 → 좌표 보간 함수가 이미 있음(RG:572 · 593). 위경도 변환 = pyproj(설치됨 · 선례 있음).
|
||||
4. 지도는 지금 VWorld 하나뿐(서버가 타일 · 주소검색을 대리). 카카오 · 다음은 코드 · `.env` 어디에도 없음 → 키부터 새로 받아야 함.
|
||||
5. 카카오 길찾기 응답 = 총 거리 · 도로명별 거리 · 좌표뿐. 도로 종류 · 차로 · 포장 정보 없음 → 2차포장 · 1차포장 · 비포장 나누기는 사용자 입력이 맞음.
|
||||
6. 견본 엑셀은 1차 · 2차를 「포장」 한 칸으로 합쳐 단가산출에 씀(L1 포장 · L2 비포장 · 속도 V1~V4). 단가에 쓰이는 축은 포장 · 비포장 둘.
|
||||
|
||||
## 2. 지금 B08 화면 짜임 · 붙일 자리
|
||||
|
||||
- 메인 탭 = `TABS` 넷(구조물 집계표 · 자재 · 토공 · 수리집수면적표 · PG:30-35) · `select()`가 단추 줄을 다시 그리고 `renderTab()`(PG:86-105)이 탭마다 새 몸통을 붙임(늦은 응답이 남의 탭을 덮지 않게 함).
|
||||
- 하위 탭 = 같은 꼴의 sm 단추 줄 — 자재 `SHEETS`(PG:40-83) · 토공 `SHEETS` 넷(`B08_Quantity_UI_Earthwork.ts:240-245 · 292-320`). 하위 탭이 없는 탭은 높이만 채우는 빈 줄(PG:90-100).
|
||||
- B09 는 두 층 탭 줄을 묶은 `createTabBars`(TB:35-77)가 있으나 B09 전용 · 탭 목록 고정.
|
||||
- 좌측 패널 = 「메인 탭과 같은 컨테이너」(OP:2 · `card()` OP:84-93) + [저장] 한 줄 · 캐시 `b08-options`(sessionStorage · `A00_Common/b_page_state.ts` `readState`·`writeState`) → [저장] PUT.
|
||||
- 붙일 자리: ① PG `TABS` 다섯째 `milestone` + `renderTab` 가지 + 글자 키(`ui_template_locale_b4.ts` B08 줄 옆) ② 새 파일 하나에 하위 탭 줄 — 첫 탭 「거리이정표」(고정) · 다음부터 경로 탭(업체마다) · 줄 끝 [+ 추가] · [삭제] ③ OP 에 「거리이정표」 컨테이너(공사지 · 기준점 칸). PG 는 154줄이라 넉넉함.
|
||||
|
||||
## 3. 지금 프로그램 안 거리 · 운반 값
|
||||
|
||||
| 자리 | 단위 · 값 | 받는 곳 | 이정표와 관계 |
|
||||
|---|---|---|---|
|
||||
| B08 토공 평균운반거리 · 무대운반 | m · 유토곡선 배분(`mass_haul.haul_plan`) | B05~B07 자동 | 현장 안 흙 운반 — 별개 |
|
||||
| `project_settings.json › quantity` `spoil_site_distance_m` · `topsoil_haul_distance_m` | m · 기본 None | 칸만 있고 읽는 곳 없음 | 사토장 · 표토 거리 — 별개 |
|
||||
| B09 운반 줄(중기 · 기계 · 모래 · 자갈 · 시멘트 · 철근운반 · BI:50-57) | 수량만 B08 총괄자재 · 단가 「연결 없음」(BI:21) | — | **잇는 자리 후보 1** |
|
||||
| B09 단가산출근거(산근) | 「조합 밖 운반 산근 = 원천 없음」(SG:22) | — | **후보 2** — 산근 입력 L(포장) · L(비포장) |
|
||||
| M01 로직(L10) | GF000136 혼합골재 운반 = 입력 Cm(분) · GF000137 중기운반 = 입력 t2(분) · GF000284 덤프운반 = 운반거리 ㎞ 하나 | 사용자 · 견본 예시값 | **후보 3** — 포장 · 비포장 둘로 나눈 입력이 없음(견본 꼴로 가려면 입력 늘림) |
|
||||
| 구조물정의 · M02 조합 | 거리 칸 없음 | — | 없음 |
|
||||
|
||||
- 견본 단가산출(1315-1339행) 혼합골재 운반: L1 포장 25.1 km(= 이정표 O25) · L2 비포장 0.8 km(= R25) · V1 30 · V2 35 · V3 10 · V4 15 km/h · t2 = (L1/V1 + L1/V2 + L2/V3 + L2/V4)×60 = 101.23 분. 시트끼리 수식 연결 없음 — 손으로 옮겨 적음.
|
||||
- 속도 근거 = 건설표준품셈 8-2-8 덤프트럭 「운반도로와 평균주행속도」(`resources/knowledge/original/원가계산/건설공사_표준품셈/본문/01_공통부문/제08장_건설기계/8-02-08_덤프트럭.md:44-66`) — 2차로 이상 공사용도로 30 · 35 / 교차 힘든 산간지도로 10 · 15. 임도 안 토사 덤프는 QF000337 V1 5 · V2 6.
|
||||
- 견본 표 수식: 장비(거창군청→시점) = 2차 23.8 + 1차 0.6 + 비포장 0.8 · 자재(골재원 · 김천역→임도중점) 비포장 = 0.8 + X10(시점→중점 · 견본은 빈칸) · 포장 = 2차 + 1차 · 합계 = 포장 + 비포장.
|
||||
|
||||
## 4. 시점 · 중점 좌표
|
||||
|
||||
- 설계 노선 정본 순서(RG:300-305): `B05_Profile/route/planned_route.csv`(수정본) → `planned_route_initial.csv` → 예상노선 → `initial_snapshot/planned_route.csv`. 열 = sequence · x · y · 값은 프로젝트 작업 좌표계(m · storage 견본 x≈208,403 · y≈367,920).
|
||||
- 좌표계 = `project_epsg_from_prj(root)` · 사다리 창구 `resolve_project_crs`(CRS:231-261 · 폴백 EPSG:5186). DB `projects.crs_epsg`(기본 5178)는 라벨일 뿐 · 실좌표와 다른 사례 기록 있음.
|
||||
- 위경도 = `pyproj.Transformer.from_crs(작업 좌표계, "EPSG:4326", always_xy=True)` — 선례 `B04_PreProcess_Engine_Extent.py:189` · `B04_PreProcess_Engine_VWorld.py:96`. 전용 함수는 없으나 한 줄.
|
||||
- 중점: `build_route_vertices`(RG:572) + `interpolate_vertex(정점, 누가거리 m)`(RG:593)로 측점 거리 → x · y. 「사용자가 거리 입력」 그대로 가능 · 기본 후보 = 노선 연장 ÷ 2(「임도중점」).
|
||||
- 시점→중점 km = 그 측점 거리 그대로(임도 위 = 비포장). 견본 X10 칸의 자리.
|
||||
- 기준점(병곡리 968-31) 검색 씨앗 = `projects.region`(지역명) · 지번 주소 검색은 VWorld · 카카오 둘 다 됨.
|
||||
|
||||
## 5. 지금 지도 쓰임 · 키
|
||||
|
||||
- B01 회사 주소 지도: VWorld 주소검색 · 후보 검색 · WMTS 배경 타일을 서버가 대리(MAP · `GET /dashboard/map/tile/{z}/{x}/{y}` `B01_Dashboard_Router.py:213`) · 화면 = 라이브러리 없이 타일 3×3 img(`B01_Dashboard_UI_MapPreview.ts` · Web Mercator 타일 수식 `tileIndex` :21) · 주소 칸 `B01_Dashboard_UI_AddressField.ts`.
|
||||
- B04 · B05 지도: 자체 Canvas 그리기 + VWorld(`B04_PreProcess_UI_MapViewer.ts` · `B05_Profile_UI_RouteEdit_Recommend_Map.ts`).
|
||||
- `maplibre-gl` = `package.json` 의존성 · vite alias 뿐 · import 0. Leaflet · OpenLayers · 카카오 · 다음 = 0.
|
||||
- `.env` 지도 키 이름 = `VWORLD_LOGIN_ID` · `VWORLD_LOGIN_PW` · `VWORLD_SESSION_COOKIE` 뿐 · KAKAO · DAUM 없음. VWorld API 키는 `config_system` 에 없고 `B04_PreProcess_Engine_VWorld.py:22-29` 코드 안 폴백 값을 씀(값 생략).
|
||||
- CSP 머리 없음 → 외부 `sdk.js` 로드 막힘 없음. Pillow 12.3 · pyproj 3.7 · httpx 설치됨.
|
||||
|
||||
## 6. 다음(카카오) 지도 API 외부 조사 (2026-10 기준 문서)
|
||||
|
||||
| 쓰임 | 길 · 조건 | 무료 · 요금 | 막힘 |
|
||||
|---|---|---|---|
|
||||
| 지도 보기 | JS SDK `dapi.kakao.com/v2/maps/sdk.js?appkey=` · JavaScript 키 · 키의 「JavaScript SDK 도메인」에 `http://localhost:5173` · 운영 주소 등록(프로토콜 · 포트까지 · 어긋나면 401) · 앱에서 카카오맵 사용 설정 ON · 선 = `kakao.maps.Polyline` | 일 300,000 | JS 키는 브라우저에 보이는 것이 전제 · 도메인 제한이 보호 |
|
||||
| 주소 → 좌표 | `dapi.kakao.com/v2/local/search/address`(지번 · 도로명) · `…/search/keyword` · 좌표계 변환 `…/geo/transcoord`(WGS84 · WTM · TM 등) · 머리 `Authorization: KakaoAK {REST 키}` | 일 100,000 | FAQ 「로컬 API 응답 별도 저장 금지」 — 업체 좌표를 파일에 두면 회색 |
|
||||
| 길찾기 | `apis-navi.kakaomobility.com/v1/directions` GET · origin · destination = 「경도,위도」 · 경유지 ≤ 5 · 응답 `summary.distance`(m) · `duration`(초) · `fare`(택시 · 통행료) · `sections[].roads[]` = name · distance · duration · traffic_speed · traffic_state · vertexes(경도 · 위도 평면 배열) · `guides[]` | 일 10,000 · 초과 8원/건 | 도로 종류 · 등급 · 차로 · 포장 필드 없음(`road_details` 는 추가 필드가 문서에 없음) · 상업 이용은 제휴 필요라는 답변이 있음(데브톡 · 엇갈림) |
|
||||
| 지도 그림 | 정적 지도 `dapi.kakao.com/v2/maps/staticmap` · center · lv 1~15 · size ≤ 2048×1024 · markers ≤ 5 · 응답 = 이미지 바이트 · 로고 못 지움 | 일 1,000 · 초과 2원 | **선 · 경로 파라미터 없음** → 길 선은 서버가 덧그려야 함 · 레벨별 축척 문서 없음(맞춤 실측 필요) |
|
||||
| 화면 캡처 | JS 지도 타일 = 다른 출처 이미지 | — | canvas 오염으로 `toDataURL` 막힐 공산(데브톡 미해결 문의) · 지도 이미지 저장 · 배포는 약관 회색 |
|
||||
| 정책 | 2026-07-21 개편 — 계정에서 처음 켠 앱만 무료 쿼터 · 그 밖 · 초과 = 비즈월렛 유료 · 초과 시 429 | — | — |
|
||||
|
||||
- 키 숨김: REST 키(주소 · 길찾기 · 정적 지도) = 서버만(`.env` 새 키) · JS 키 = 화면에 넘김(서버 설정 길 또는 Vite env).
|
||||
- 길찾기 도착점이 임도 시점이면 API 가 가장 가까운 등록 도로에 붙임 → 마지막 비포장 · 임도 구간은 응답 거리에 안 들거나 어긋남 → 사용자 km 칸 필요.
|
||||
|
||||
## 7. 도로 구분(2차포장 · 1차포장 · 비포장)
|
||||
|
||||
- 응답으로 자동 판정 불가: roads 에는 도로명 · 거리 · 실시간 속도만 있음 · 「○○로」 이름으로 차로 수 · 포장 여부를 알 수 없음 · traffic_speed 는 교통 상태라 도로 등급 대용 아님.
|
||||
- 맞는 방식 = 경로마다 km 칸 셋(2차포장 · 1차포장 · 비포장) 사용자 입력 · 길찾기 총 km 는 도움값(기본으로 2차포장 칸에 넣고 사용자가 나눔) · 도로명별 거리 목록을 곁에 보여 나누기 도움.
|
||||
- 견본 짜임이 이를 받침: 업체→기준점 = 2차포장 하나 · 기준점→시점 = 1차포장(0.6) · 시점 쪽 = 비포장(0.8) — 1차 · 비포장은 업체가 달라도 같은 공통 구간 → 기준점이 있으면 공통 구간 km 를 한 번만 적음.
|
||||
|
||||
## 8. 설계 갈래 · 추천
|
||||
|
||||
- 데이터 모양(한 파일): 공사지 = 시점 측점(0) · 중점 측점(m · 사용자) / 기준점 = 없음 또는 {이름 · 주소 · 기준점→시점 km 셋} / 경로 목록 = [{업체 이름 · 주소 · 도착(기준점 · 시점) · 길찾기 총 km · km 셋 · 쓰임 줄[{구분 · 도착 시점 · 중점 · 비고}] · 그림 파일 이름}].
|
||||
- 표 한 줄 = 경로 km 셋 + (기준점 경유면 기준점→시점 km) + (도착 = 중점이면 시점→중점 km 를 비포장에) · 포장 = 2차 + 1차 · 합계 = 포장 + 비포장 — 견본 수식과 같음. 장비 20톤 · 8톤처럼 한 업체 두 줄 = 쓰임 줄 둘.
|
||||
- 정본 자리 = 프로젝트 storage `B08_Quantity/milestone/`(json 한 벌 + 경로 그림 png · 폴더가 목록 — B09 견적서 파일 길 `B09_Estimation_Router_Quotes.py` 꼴) · DB 표 없음. 초기값 층 없음(자동설계가 낳는 값 아님 · 시점 좌표는 읽을 때마다 노선에서). 캐시 `b08-milestone` → [저장]. 업체 좌표는 저장하지 않고 주소 글만(카카오 로컬 저장 금지 회피 · 열 때 다시 찾음).
|
||||
- 계산 자리: 주소 검색 · 길찾기 · 시점 · 중점 위경도 · 경로 그림 = ③ 서버 단독(REST 키 숨김 · [길찾기] 누를 때만 왕복 · 조작 중 계산 아님) / 표 합 = ① 파이썬 · TS 짝(두 파일 머리 표기 + 거울 시험 · 화면 즉시 · [저장] 때 서버가 다시 셈) / 화면 지도 = 카카오 JS(그리기만).
|
||||
- 경로 그림 갈래: **A 서버 그림** — VWorld 배경 타일(이미 서버 대리 · Web Mercator 수식 있음) + 길찾기 vertexes 선 + 업체 · 기준점 · 시점 표지 · Pillow · 같은 출처라 막힘 없음 · 카카오 저장 약관 비껴감 · 바탕이 다음 지도 아님 / **B 카카오 정적 지도 + 서버 덧그림** — 바탕 = 다음 지도 · 선 맞춤을 실측으로 · 저장 약관 회색 / **C 화면 캡처** — CORS 로 깨질 공산 / **D 사진 올리기** — 가장 단순. 추천 = 보기는 카카오 JS · 저장 그림은 A · D 를 늘 곁에.
|
||||
- 화면: 메인 「거리이정표」 → 하위 탭 [거리이정표](상자 그림 SVG + 공용 표 자동 · 업체 → 기준점 → 시점 → 중점 · 선마다 도로 구분 · km) · [경로1 · 업체명] … · [+ 추가] · [삭제] / 경로 탭 = 컨테이너 하나(위 = 업체 · 주소 검색 · 도착 · [길찾기] · km 셋 · 쓰임 줄 · 아래 = 지도 + 그림 한 장) / 좌측 컨테이너 = 공사지(중점 측점) · 기준점(있음 · 없음 · 이름 · 주소 · 공통 km 셋).
|
||||
- 새 파일 후보: 화면(하위 탭 · 경로 컨테이너) · 상자 그림 · 표 · 라우터(GET · PUT · 주소 · 길찾기 · 그림) · 합 짝(.py · .ts) · 시험 `resources/tester/`. 카카오 키가 오기 전에도 km 손 입력 · 사진 올리기로 먼저 쓸 수 있게 길찾기는 덧붙이는 칸으로.
|
||||
|
||||
## 9. 사용자에게 물을 것
|
||||
|
||||
1. 경로 그림 바탕 — A 서버 그림(VWorld 바탕 + 길 선) vs B 다음 정적 지도 바탕. 추천 A + 사진 올리기(다음 지도는 화면 보기용).
|
||||
2. 카카오 키 — 카카오 개발자 앱 하나(첫 앱이어야 무료) · JavaScript 키(도메인 `http://localhost:5173` + 운영 주소 등록) · REST API 키 발급은 사용자 몫. 판매 프로그램이면 카카오모빌리티 제휴 문의 필요 공산. 추천: 키 전에는 손 입력판부터.
|
||||
3. 도로 구분 나누기 — 추천: 업체→기준점 길찾기 km 전부 「2차포장」 기본 + 사용자가 고침 · 기준점→시점 공통 구간(1차포장 · 비포장)은 기준점 칸에 한 번만 입력.
|
||||
4. 표 「구분」 줄 — 견본 다섯(장비 20톤 · 8톤 · 혼합골재 · 전석운반 · 철근) 고정 vs 자유. 추천: 경로 탭 안 쓰임 줄 자유 + 견본 다섯을 고르기 목록으로.
|
||||
5. 중점 기본값 — 추천: 노선 연장 ÷ 2 측점 기본 · 사용자가 고침 · 시점→중점 = 비포장으로 자동 더함.
|
||||
|
||||
출처: [카카오 쿼터](https://developers.kakao.com/docs/ko/getting-started/quota) · [카카오맵 개요](https://developers.kakao.com/docs/ko/kakaomap/common) · [카카오맵 REST(정적 지도 · 좌표 변환 · 주소)](https://developers.kakao.com/docs/ko/kakaomap/rest-api) · [로컬 개요](https://developers.kakao.com/docs/ko/local/common) · [자동차 길찾기](https://developers.kakaomobility.com/guide/navi-api/directions) · [길찾기 가격](https://developers.kakaomobility.com/price) · [2026-07-21 개편 공지](https://devtalk.kakao.com/t/api-notice-on-new-kakao-map-api-features-and-free-quota-policy/150222) · [길찾기 무료 쿼터 답변](https://devtalk.kakao.com/t/api-directions-api/151192) · [JS SDK 도메인 401](https://devtalk.kakao.com/t/js-sdk-401-domain-mismatched-https-4fugfgg-anonymous-8081-exp-direct-caller-30/151184) · [지도 캡처 CORS 문의](https://devtalk.kakao.com/t/api/137347)
|
||||
Reference in New Issue
Block a user