-
🌸 Next.js와 Python으로 만든 광주시 벚꽃 명소 지도 프로젝트사이드 프로젝트 기록 2025. 3. 27. 00:51
안녕하세요! 오늘은 Python과 Next.js를 활용하여 광주시의 벚꽃 명소를 소개하는 웹 애플리케이션을 개발한 경험을 공유합니다. 특히 화면정의서, 기능정의서 작성부터 시작해 데이터 수집과 웹 서비스 구현까지의 풀스택 개발 과정에서 마주한 다양한 도전과 오류 해결 과정을 자세히 소개하겠습니다.
📍 프로젝트 소개
본 프로젝트는 크게 다음과 같은 흐름으로 진행되었습니다.
- 기획 단계
- 화면정의서 및 기능정의서 작성
- 데이터 수집 및 가공 (Python)
- 웹 인터페이스 구현 (Next.js)
📑 화면정의서 작성하기
화면정의서는 서비스의 화면 구성과 사용자 경험(UX)을 미리 정의하는 단계입니다. 저는 다음과 같은 방식으로 화면정의서를 작성했습니다.
- 주요 화면 구성 요소
- 네이버 지도 영역
- 장소별 커스텀 마커 디자인
- 마커 클릭 시 상세 정보 모달
- 드라이브 코스 표시 및 세부 경로 폴리라인
화면정의서를 통해 명확한 디자인 방향성을 설정했고, 이후 개발 속도와 정확성이 크게 향상되었습니다.
📝 기능정의서 작성하기
기능정의서는 프로젝트에서 구현할 기능들을 명확히 정의하는 문서로, 다음과 같이 작성했습니다.
기능 분류세부 기능 설명우선순위메인 화면 지도 표시 (네이버 지도 API 활용) 상 벚꽃 명소 위치 마커 표시 (커스텀 마커) 상 마커 클릭 시 상세 정보 팝업 상 드라이브 코스 드라이브 코스 선택 시 폴리라인으로 경로 표시 상 드라이브 코스별 주요 지점 간단 정보 표시 중 부가 기능 실시간 날씨 정보 위젯 (OpenWeather API 연동) 하 기능정의서를 작성함으로써 개발 초기에 우선순위를 명확히 할 수 있었고, 빠른 MVP 구현이 가능했습니다.
🐍 Python을 활용한 데이터 수집
Python으로 벚꽃 명소의 위치 데이터를 네이버 지도 API를 통해 수집했습니다.
네이버 지도 API를 통한 위경도 수집
def get_lat_lng(address): url = f"https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query={address}" headers = {...} response = requests.get(url, headers=headers).json() if response["addresses"]: return float(response["addresses"][0]["y"]), float(response["addresses"][0]["x"]) return None, None
드라이브 경로 데이터 수집
def get_route_path(start_lng, start_lat, goal_lng, goal_lat): url = f"https://naveropenapi.apigw.ntruss.com/map-direction/v1/driving?start={start_lng},{start_lat}&goal={goal_lng},{goal_lat}&option=trafast" headers = {...} response = requests.get(url, headers=headers).json() return response["route"]["trafast"][0]["path"] if 'route' in response else []
🌐 Next.js 웹 인터페이스 구현
Next.js를 활용해 웹 UI를 구현했고, 특히 드라이브 코스를 지도 위에 폴리라인으로 표시하는 기능을 구현하며 문제가 발생했습니다.
주요 오류 사례와 해결 과정 (폴리라인 오류)
🔴 오류의 정의
- 드라이브 코스의 폴리라인이 경로 전체를 제대로 표시하지 않고 특정 구간이 직선으로 연결되는 오류가 발생했습니다.
🟡 내 코드의 문제점
- 좌표 데이터 배열의 순서가 실제 경로 순서와 다르게 구성되어 있었습니다.
- 주요 지점 사이의 중간 경로 좌표가 부족해 부자연스러운 직선 연결이 생겼습니다.
🟢 해결 방법
- 좌표 배열을 실제 주행 경로 순서에 맞게 다시 정렬하고 중간 좌표를 보완했습니다.
- 네이버 Directions API를 활용하여 정확한 도로 경로를 자동으로 받아오는 방식으로 개선했습니다.
- 아래는 해결된 폴리라인 코드 예시입니다.
// 드라이브 코스 폴리라인 생성 (수정 후) const path = driveCourse.points.map(p => new naver.maps.LatLng(p.latitude, p.longitude)); const polyline = new naver.maps.Polyline({ map, path, strokeColor: "#FF6F91", strokeWeight: 5, strokeOpacity: 0.8 }); // 지도 영역 자동 조정 const bounds = new naver.maps.LatLngBounds(); path.forEach(coord => bounds.extend(coord)); map.fitBounds(bounds);
🛠 주요 기술적 도전과 해결 방법
이외에도 개발 과정에서 다음과 같은 기술적 문제들을 경험하고 해결했습니다.
- API 호출 제한
- 문제: 네이버 API 호출 제한 초과로 요청 실패
- 해결: API 호출 사이 time.sleep() 및 재시도 로직 추가
- 정확한 좌표 검증
- 문제: 일부 주소의 위도/경도 변환 오류
- 해결: 변환된 좌표 데이터를 구글 맵 등에서 교차 검증
- Next.js 성능 최적화
- 문제: 다수 마커 렌더링 시 성능 저하
- 해결: 마커 컴포넌트 메모이제이션 및 동적 렌더링 처리
🎯 향후 개선 계획
- 실시간 벚꽃 개화 정보 API 연동
- 사용자 위치 기반 명소 추천 기능
- 커뮤니티 기능 추가(방문 후기, 사진 공유)
🔍 프로젝트를 통해 배운 점
- 기획의 중요성 (화면정의서, 기능정의서 작성의 가치)
- 데이터 파이프라인을 효율적으로 구축하는 방법
- 실사용자를 고려한 UX/UI 디자인 구현법
- 실제 개발 과정에서 마주하는 기술적 문제 해결 능력
마치며
이번 프로젝트는 특히 화면정의서와 기능정의서를 작성하는 초기 단계의 중요성을 깨닫게 해준 소중한 경험이었습니다.
기획 단계에서 명확하게 정의된 문서는 프로젝트의 방향성을 잡아줬고, 폴리라인 오류와 같은 구체적인 기술적 문제를 명확히 분석하고 해결하는 데 큰 도움이 되었습니다.전체 소스 코드는 GitHub에서 확인하실 수 있습니다:
반응형 - 기획 단계