Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Walkthrough버스 오버레이에 이전 위치(previousBusPositions) 저장과 각도 계산(calculateAngle)을 추가하여, 이전 위치 기준으로 회전(rotation)을 계산·적용하고 사용되지 않는 이전 위치를 정리(cleanup)합니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant App as 앱 (버스 데이터 공급)
participant Overlays as mapOverlays.ts
participant PrevMap as previousBusPositions
participant Icon as BusIcon (DOM)
App->>Overlays: 최신 버스 목록 전달
Overlays->>PrevMap: activeBusIds 계산 및 이전 위치 정리
loop 각 버스
Overlays->>PrevMap: 이전 위치 확인 (busId)
alt 이전 위치 있음
Overlays->>Overlays: calculateAngle(prevPos, curPos)
Overlays->>Icon: CSS transform(rotate(calculated)) + transition 적용
Overlays->>PrevMap: 이전 위치 및 rotation 갱신 저장
else 이전 위치 없음
Overlays->>Icon: 기본 방향 설정 (no rotate)
Overlays->>PrevMap: 현재 위치 저장
end
end
Note over Overlays,PrevMap: 오버레이 제거 시 cleanup 함수로 PrevMap에서 해당 busId 제거
예상 코드 리뷰 노력🎯 3 (중간 난이도) | ⏱️ ~20분
시
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/utils/mapOverlays.ts (2)
14-31: 각도 계산 정확성 검증 필요현재 구현은 위경도 좌표를 직교 좌표처럼 취급하여 각도를 계산합니다. 카카오맵의 Web Mercator 투영에서는 짧은 거리에서 작동할 수 있지만, 거리나 위도에 따라 정확도가 떨어질 수 있습니다.
다음을 확인해 주세요:
- 버스 간 이동 거리가 일반적으로 얼마나 되는지
- 실제 테스트에서 버스 아이콘이 올바른 방향을 가리키는지
필요시 더 정확한 지리적 방위각(bearing) 계산을 구현하도록 도와드릴 수 있습니다. 다음은 정확한 구현 예시입니다:
const calculateAngle = ( prevLat: number, prevLng: number, currLat: number, currLng: number ): number => { // 라디안으로 변환 const lat1 = prevLat * (Math.PI / 180); const lat2 = currLat * (Math.PI / 180); const deltaLng = (currLng - prevLng) * (Math.PI / 180); // 방위각 계산 const y = Math.sin(deltaLng) * Math.cos(lat2); const x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLng); const angleRad = Math.atan2(y, x); // 도(degree)로 변환 및 정규화 (0-360) const angleDeg = (angleRad * (180 / Math.PI) + 360) % 360; return angleDeg; };더 정확한 계산이 필요하신가요?
233-233: 버스 ID 생성 방식 개선 권장
shuttleId가 없을 때 좌표를 문자열로 연결하여 ID를 생성하는 방식은 부동소수점 정밀도 문제를 일으킬 수 있습니다. 같은 버스의 위치가 미세하게 다르게 보고될 경우 다른 버스로 취급될 수 있습니다.가능하면 다음 방법을 고려하세요:
- API에서 항상 고유한
shuttleId를 제공하도록 보장- 또는 좌표를 일정 정밀도로 반올림하여 ID 생성:
const busId = bus.shuttleId || `${bus.lat.toFixed(6)}-${bus.lng.toFixed(6)}`;다만, 이 방식도 여러 버스가 정확히 같은 위치에 있을 경우 충돌 가능성이 있으므로,
shuttleId를 항상 제공하는 것이 가장 안전합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/utils/mapOverlays.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.
🔇 Additional comments (1)
src/utils/mapOverlays.ts (1)
272-275: CSS 회전 애니메이션 구현이 적절합니다
transform,transformOrigin,transition속성을 사용한 회전 애니메이션이 올바르게 구현되었습니다. 0.3초의 ease-out 전환 효과로 부드러운 회전이 가능합니다.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/utils/mapOverlays.ts (1)
232-272: 메모리 정리 + 회전 상태 유지 로직이 이전 리뷰 지적을 잘 해소합니다
activeBusIds집합을 만든 뒤,previousBusPositions를 순회하며 비활성 버스를 삭제하는 부분이 이전에 지적되던 메모리 누수 위험을 실질적으로 해결해 줍니다.- 각 버스별로
previousData를 조회해서
- 좌표가 변하면
calculateAngle로 새 각도를 계산하고- 좌표가 그대로면
previousData.rotation을 재사용하는 패턴 덕분에, 정지 시 아이콘이 0°로 튀는 문제도 잘 막혔습니다.- 이후에
{ lat, lng, rotation }을 다시previousBusPositions에 저장해서, 다음 렌더 시 일관된 상태를 갖게 되는 흐름도 자연스럽습니다.소소한 개선 아이디어(선택 사항)입니다:
busId생성 시bus.shuttleId || \${bus.lat}-${bus.lng}`대신??`를 사용하면, 빈 문자열이 유효한 ID일 때도 안전합니다.shuttleId가 없는 버스는 좌표 기반 ID라 이동할 때마다 다른 ID로 인식되어 회전 이력이 이어지지 않습니다. 실제 데이터에서 항상shuttleId가 들어온다면 문제 없지만, 그렇지 않을 가능성이 있다면 타입이나 주석으로 “rotation은 shuttleId가 있는 버스에 한해 연속성을 기대한다”는 점을 명시해 두면 혼동을 줄일 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/utils/mapOverlays.ts(4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: KwonDeaGeun
Repo: KwonDeaGeun/WhatTheBus-Web PR: 21
File: src/App.tsx:16-23
Timestamp: 2025-09-22T04:45:54.455Z
Learning: KwonDeaGeun은 TypeScript에서 any 타입 사용을 피하고 더 타입 안전한 코드를 선호한다.
🧬 Code graph analysis (1)
src/utils/mapOverlays.ts (1)
src/data/bus.ts (1)
buses(8-39)
🔇 Additional comments (3)
src/utils/mapOverlays.ts (3)
10-31: 이전 위치 상태 구조와 각도 계산 유틸이 전반적으로 잘 설계되어 있습니다
previousBusPositions에rotation까지 함께 저장하는 구조 덕분에, 정지 시에도 방향을 유지할 수 있고 이후 로직이 단순해져서 좋습니다.
calculateAngle도deltaLat,deltaLng를 이용해 북쪽(위도 증가 방향)을 0°로 두고 시계방향으로 증가하는 형태라, 주석의 의도(“북쪽 기준, 시계방향”)와 잘 맞습니다.다만 실제 버스 아이콘의 기본 방향(0°일 때 어느 방향을 바라보는지)과 지도의 좌표계가 이 수학적 정의와 완전히 일치하는지는, 맵에서 실제 움직임을 한 번 눈으로 확인해 보시는 걸 권장드립니다.
289-292: CSS 회전 적용 방식이 의도에 잘 맞습니다
rotate(${rotation}deg)에transformOrigin = "center center"와transition: transform 0.3s ease-out을 함께 적용해서, 방향 변경 시 부드럽게 회전하고 중심을 기준으로 도는 동작이 자연스럽게 보일 것 같습니다. 이 부분은 그대로 두셔도 무방해 보입니다.
303-311: cleanup에서 상태까지 함께 정리하는 설계가 좋습니다
createBusOverlays가 반환하는 핸들에cleanup을 추가하고, 그 안에서previousBusPositions.delete(busId)를 호출한 것은 상태 수명과 오버레이 수명을 맞춰 주는 좋은 패턴입니다. 상단의activeBusIds기반 스위핑과 함께 동작해서, 오버레이 제거 시점에도 즉시 정리되고, 폴링 주기마다 한 번 더 안전망이 있는 형태라 메모리 관점에서 안정적입니다.
Summary by CodeRabbit