Skip to content

feat: 버스 이전 데이터로 버스 이동 방향으로 회전 구현#31

Merged
KwonDeaGeun merged 2 commits intomainfrom
feat/add-bus-rotate
Nov 15, 2025
Merged

feat: 버스 이전 데이터로 버스 이동 방향으로 회전 구현#31
KwonDeaGeun merged 2 commits intomainfrom
feat/add-bus-rotate

Conversation

@KwonDeaGeun
Copy link
Owner

@KwonDeaGeun KwonDeaGeun commented Nov 15, 2025

Summary by CodeRabbit

  • 새로운 기능
    • 버스 아이콘이 이동 방향에 따라 회전하고, 방향 변화 시 부드럽게 애니메이션됩니다.
    • 이전 위치를 기반으로 회전 상태를 보존해 불필요한 회전 재계산을 줄였습니다.
  • 버그 수정 / 개선
    • 더 이상 존재하지 않는 버스의 회전 상태와 관련 데이터를 정리해 메모리 사용을 개선했습니다.
    • 오버레이 제거 시 해당 버스의 상태가 확실히 정리됩니다.

@KwonDeaGeun KwonDeaGeun self-assigned this Nov 15, 2025
@vercel
Copy link

vercel bot commented Nov 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
what-the-bus-web Ready Ready Preview Comment Nov 15, 2025 1:21am

@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

Walkthrough

버스 오버레이에 이전 위치(previousBusPositions) 저장과 각도 계산(calculateAngle)을 추가하여, 이전 위치 기준으로 회전(rotation)을 계산·적용하고 사용되지 않는 이전 위치를 정리(cleanup)합니다.

Changes

Cohort / File(s) 변경 요약
버스 오버레이 및 상태 관리
src/utils/mapOverlays.ts
per-bus 이전 위치 저장용 previousBusPositions 추가. calculateAngle 유틸 도입. 각 버스에 대해 이전 위치가 있으면 회전 계산(위치 동일 시 기존 회전 재사용), 계산된 회전값을 CSS transform으로 적용하고 트랜지션을 설정. 사용되지 않는 busId는 정리하며, 오버레이 반환값에 cleanup 함수를 포함해 제거 시 상태를 정리.

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 제거
Loading

예상 코드 리뷰 노력

🎯 3 (중간 난이도) | ⏱️ ~20분

  • 이전 위치(state) 관리와 메모리 정리 로직(특히 activeBusIds 기반 삭제) 검증 필요
  • calculateAngle의 수학적 정확성(위치 경계, 역주행/경계 케이스) 점검
  • CSS transform 적용(원점, 트랜지션)과 렌더링/퍼포먼스 영향 확인
  • 오버레이 cleanup 경로가 모든 제거 케이스에서 호출되는지 검토

🐰 지도 위에서 바람을 읽고,
이전 점을 껴안고 각을 재어,
부드럽게 돌며 길을 찾노라,
작은 회전이 큰 흐름을 만들고,
버스들은 춤추듯 다음 정류장으로 향하네. 🚍✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 이전 버스 위치 데이터를 기반으로 버스 이동 방향으로 회전을 구현하는 것으로, 변경 사항의 주요 기능과 일치합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-bus-rotate

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/utils/mapOverlays.ts (2)

14-31: 각도 계산 정확성 검증 필요

현재 구현은 위경도 좌표를 직교 좌표처럼 취급하여 각도를 계산합니다. 카카오맵의 Web Mercator 투영에서는 짧은 거리에서 작동할 수 있지만, 거리나 위도에 따라 정확도가 떨어질 수 있습니다.

다음을 확인해 주세요:

  1. 버스 간 이동 거리가 일반적으로 얼마나 되는지
  2. 실제 테스트에서 버스 아이콘이 올바른 방향을 가리키는지

필요시 더 정확한 지리적 방위각(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를 생성하는 방식은 부동소수점 정밀도 문제를 일으킬 수 있습니다. 같은 버스의 위치가 미세하게 다르게 보고될 경우 다른 버스로 취급될 수 있습니다.

가능하면 다음 방법을 고려하세요:

  1. API에서 항상 고유한 shuttleId를 제공하도록 보장
  2. 또는 좌표를 일정 정밀도로 반올림하여 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4295213 and 2262895.

📒 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 전환 효과로 부드러운 회전이 가능합니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2262895 and 3586098.

📒 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: 이전 위치 상태 구조와 각도 계산 유틸이 전반적으로 잘 설계되어 있습니다

previousBusPositionsrotation까지 함께 저장하는 구조 덕분에, 정지 시에도 방향을 유지할 수 있고 이후 로직이 단순해져서 좋습니다.
calculateAngledeltaLat, 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 기반 스위핑과 함께 동작해서, 오버레이 제거 시점에도 즉시 정리되고, 폴링 주기마다 한 번 더 안전망이 있는 형태라 메모리 관점에서 안정적입니다.

@KwonDeaGeun KwonDeaGeun merged commit 5a769dc into main Nov 15, 2025
4 checks passed
@KwonDeaGeun KwonDeaGeun deleted the feat/add-bus-rotate branch November 15, 2025 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant