나는 힘들 때 햄토리 오프닝을 들어.
길찾기 하는 날!
일단 탭함수를 내가 막아놔서 주석을 풀고 탭 함수를 살려서 길찾기로 넘어가게 해보겠다.
먼저 parkinglot.jsp에서 영역을 만들어주었다.
<!-- 주차장 길찾기 탭 -->
<div id="route" class="tab-content" style="display: none;">
<!-- 출발지와 도착지 입력 영역 -->
<div class="route-search">
<label for="start-location">출발지:</label>
<input type="text" id="start-location" placeholder="출발지를 입력하세요">
<label for="end-location">도착지:</label>
<input type="text" id="end-location" placeholder="도착지를 입력하세요">
<button onclick="findRoute()">길찾기</button>
</div>
<!-- 길찾기 경로 표시 영역 -->
<div class="route-result">
<h3>길찾기 경로</h3>
<div id="route-directions">
<!-- 길찾기 결과가 표시될 영역 -->
</div>
</div>
</div>
🚍showTab 함수
// 탭 전환 함수
function showTab(tabName) {
// 모든 탭 콘텐츠 숨기기
document.querySelectorAll('.tab-content').forEach(tab => {
tab.style.display = 'none';
});
// 선택한 탭만 보이도록 설정
document.getElementById(tabName).style.display = 'block';
// 모든 탭 버튼에서 'active' 클래스 제거
document.querySelectorAll('.tab-button').forEach(button => {
button.classList.remove('active');
});
// 선택된 탭 버튼에 'active' 클래스 추가
document.querySelector(`[onclick="showTab('${tabName}')"]`).classList.add('active');
// 'search' 탭이 활성화될 때만 지역 선택 창을 보이게 함
const regionSelection = document.querySelector('.region-selection');
if (tabName === 'search') {
regionSelection.style.display = 'block'; // 검색 탭에서는 보이도록
const province = document.getElementById('province-select').value;
const city = document.getElementById('city-select').value;
fetchParkingLotData(province, city);
} else {
regionSelection.style.display = 'none'; // 다른 탭에서는 숨기도록
}
}
주차장 검색 탭에서 보여야 하는 지역 선택 창이 길찾기 탭에서도 보여서
주차장 검색 탭에만 보여지게 수정했다. 그리고 주차장 검색/ 주차장 길찾기 탭이 활성화 되도록 다시 살려놨다.
이 다음에는 모빌리티에서
카카오 모빌리티 API 문서
https://developers.kakaomobility.com/docs/navi-api/directions/
확인 해보기
문서 확인 필수!
기능 구현
1. 주차장 검색 시 텍스트 자동완성으로 하단에 장소명이 뜨고,
해당 장소 클릭시 마커가 지도에 찍힘.
지도에 마커가 찍히고 있고 자동완성도 잘 되고 있으니, 카카오 모빌리티 API를 통해 길찾기를 구현하면 끝!
🚋길찾기 기능 구현(카카오맵을 통한) 함수들
// 길찾기 기능 구현 자바스크립트 함수들
// 자동완성 검색 함수
function searchAutocomplete(type) {
const keyword = document.getElementById(type === 'start' ? 'start-location' : 'end-location').value;
console.log("검색 키워드:", keyword); // 디버깅을 위해 추가
if (!keyword) {
document.getElementById('search-results').style.display = 'none';
return;
}
// 장소 검색 API 호출
ps.keywordSearch(keyword, function(data, status) {
if (status === kakao.maps.services.Status.OK) {
console.log("검색 결과:", data); // 검색 결과 확인을 위해 추가
displayAutocompleteResults(data, type);
} else {
console.log("검색 실패 상태:", status); // 오류 상태 출력
document.getElementById('search-results').style.display = 'none';
}
});
}
// 자동완성 결과 표시 함수
function displayAutocompleteResults(data, type) {
const resultsContainer = document.getElementById('search-results');
resultsContainer.innerHTML = ''; // 기존 검색 결과 초기화
resultsContainer.style.display = 'block';
data.forEach(place => {
const item = document.createElement('div');
item.textContent = place.place_name;
item.onclick = () => {
console.log("선택된 장소:", place.place_name); // 디버깅 추가
selectPlace(place, type);
};
resultsContainer.appendChild(item);
});
}
// 장소 선택 함수
function selectPlace(place, type) {
const inputField = document.getElementById(type === 'start' ? 'start-location' : 'end-location');
inputField.value = place.place_name; // 선택한 장소 이름을 입력 창에 설정
// 마커 설정
const location = new kakao.maps.LatLng(place.y, place.x);
if (type === 'start') {
if (startMarker) startMarker.setMap(null); // 기존 마커 제거
startMarker = new kakao.maps.Marker({
position: location
});
startMarker.setMap(map);
} else {
if (endMarker) endMarker.setMap(null); // 기존 마커 제거
endMarker = new kakao.maps.Marker({
position: location
});
endMarker.setMap(map);
}
// 지도 중심 이동
map.panTo(location);
// 검색 결과 창 닫기
document.getElementById('search-results').style.display = 'none';
}
// 검색 결과 표시용 HTML 요소 (선택 사항)
function setupSearchResultsContainer() {
const container = document.createElement('div');
container.id = 'search-results';
container.className = 'search-results';
container.style.display = 'none';
document.body.appendChild(container);
}
// 페이지 로드 시 검색 결과 표시용 컨테이너 생성
document.addEventListener('DOMContentLoaded', setupSearchResultsContainer);
1. searchAutocomplete
사용자가 입력한 검색어를 기반으로 자동완성 장소 목록을 검색
파라미터 type: 출발지 또는 도착지를 구분하기 위한 값.
"start" 또는 "end" 값을 받아서, 검색창이 출발지인지 도착지인지를 구분
type이 "start"이면 start-location 입력 필드의 값, "end"이면 end-location 입력 필드의 값
장소 검색 API 호출
ps.keywordSearch(keyword, callback) 메서드를 사용하여 키워드 기반 장소 검색
콜백 함수로 displayAutocompleteResults를 호출하여 검색 결과를 처리
kakao.maps.services.Status.OK 외의 상태가 반환되면 검색에 실패한 것으로 판단하고, search-results 요소
2. displayAutocompleteResults 함수
searchAutocomplete 함수에서 전달받은 장소 검색 결과를 HTML로 표시하여 사용자에게 선택할 수 있는 목록 제공
파라미터 data :ps.keywordSearch로 반환된 장소 검색 결과 배열 저장
- 검색 결과 컨테이너 초기화
search-results 요소를 가져와 이전 검색 결과를 지우고 display: block으로 표시 - 검색 결과 목록 생성
data 배열을 반복하여 각 장소에 대해 div 요소를 생성하고,
textContent에 place.place_name을 설정해 장소 이름을 표시 - 클릭 이벤트 추가
각 div 요소에 onclick 이벤트를 추가하여, 장소가 선택될 때 selectPlace 함수 호출
클릭 시, 선택된 place와 type이 selectPlace 함수로 전달
3. selectPlace 함수
사용자가 검색 결과에서 선택한 장소를 입력 필드에 설정하고, 지도에 마커 표시
파라미터 place: 사용자가 선택한 장소 객체
place.place_name, place.y, place.x 등의 정보를 포함
- place.y와 place.x를 사용하여 선택된 장소의 좌표를 location 변수에 설정
(type이 "start"이면 기존의 startMarker를 삭제하고 새 마커를 생성하여 지도에 표시
type이 "end"이면 기존의 endMarker를 삭제하고 새 마커를 생성하여 지도에 표시 - 지도 중심 이동
map.panTo(location)을 사용하여 지도의 중심을 선택된 장소로 이동 - 검색 결과 창 닫기
장소를 선택한 후, search-results 요소를 숨김
💥코드 흐름 요약
페이지 로드 시 setupSearchResultsContainer가 실행되어 #search-results 요소 생성
↓
사용자가 출발지 또는 도착지 입력 필드에 키워드를 입력하면
searchAutocomplete 함수가 호출되어 카카오 장소 검색 API로 장소를 검색
↓
검색 결과가 반환되면 displayAutocompleteResults 함수가 호출되어 #search-results에 자동완성 목록이 표시
↓
사용자가 목록에서 장소를 선택하면 selectPlace 함수가 호출되어 선택한 장소가 입력 필드에 설정되고,
지도에 마커가 표시
↓
선택 후 지도 중심이 해당 장소로 이동하고, 검색 결과 목록이 숨겨짐
꺄르르~~~
이제 밥 먹고 와서 카카오 모빌리티로 길찾기 네비기능을 완료해 보겠습니다!
헤헷
길찾기 기능 구현
1. 출발지와 도착지의 좌표 저장
2. 길찾기 API 요청 보내기
3. 경로 안내 결과 표시
앞선 단계에서 프론트를 다 짜놨고, 맵이랑 검색 기능이 연동되게 해놨으니까
이제 모빌리티에서 가져온 api로 기능만 구현하면 된다
🌐1. 출발지와 도착지의 좌표 저장
// 출발지와 도착지의 좌표를 저장할 변수
let startCoords = null;
let endCoords = null;
function selectPlace(place, type) {
const inputField = document.getElementById(type === 'start' ? 'start-location' : 'end-location');
inputField.value = place.place_name; // 선택한 장소 이름을 입력 창에 설정
// 선택된 장소의 좌표 저장
const location = `${place.x},${place.y}`; // 경도, 위도 형식
if (type === 'start') {
startCoords = location;
console.log("출발지 좌표 저장:", startCoords); // 출발지 좌표 확인용 로그
if (startMarker) startMarker.setMap(null); // 기존 마커 제거
startMarker = new kakao.maps.Marker({
position: new kakao.maps.LatLng(place.y, place.x)
});
startMarker.setMap(map);
} else {
endCoords = location;
console.log("도착지 좌표 저장:", endCoords); // 도착지 좌표 확인용 로그
if (endMarker) endMarker.setMap(null); // 기존 마커 제거
endMarker = new kakao.maps.Marker({
position: new kakao.maps.LatLng(place.y, place.x)
});
endMarker.setMap(map);
}
// 지도 중심 이동
map.panTo(new kakao.maps.LatLng(place.y, place.x));
// 검색 결과 창 닫기
document.getElementById('search-results').style.display = 'none';
}
selectPlace
사용자가 자동완성 목록에서 출발지 또는 도착지 장소를 선택했을 때 호출
선택한 장소를 기반으로 좌표를 저장하고, 지도에 마커를 표시하며, 입력 창에 선택한 장소 이름을 설정하는 역할
startCoords와 endCoords
출발지와 도착지의 좌표를 문자열 형식으로 저장한다.
위도와 경도에 대한 좌표를 잘 저장하고 있는 모습을 볼 수 있다.
🧴2. 길찾기 API 요청 보내기
//길찾기 API 호출 및 결과 표시
function findRoute() {
// 출발지와 도착지 좌표가 모두 설정되었는지 확인
if (!startCoords || !endCoords) {
alert("출발지와 도착지를 모두 선택해 주세요.");
return;
}
// 길찾기 API 요청 URL 생성
const url = `https://apis-navi.kakaomobility.com/v1/directions?origin=${startCoords}&destination=${endCoords}&priority=RECOMMEND&car_fuel=GASOLINE&car_hipass=false&alternatives=false&road_details=false`;
// 길찾기 API 호출
fetch(url, {
method: 'GET',
headers: {
'Authorization': `KakaoAK ${REST_API_KEY}` // REST API 키 설정
}
})
.then(response => response.json())
.then(data => {
console.log('경로 데이터:', data); // 받은 경로 데이터 확인
displayRoute(data); // 경로 데이터를 화면에 표시하는 함수 호출
})
.catch(error => {
console.error("API 요청 실패:", error);
alert("길찾기 API 요청에 실패했습니다.");
});
}
findRoute 함수는
사용자가 설정한 출발지와 도착지의 좌표를 기반으로
카카오 모빌리티 길찾기 API에 요청을 보내고, 응답으로 받은 경로 데이터를 화면에 표시
🍄3. 경로 안내 결과 표시
//경로 데이터 표시
function displayRoute(data) {
const routeDirections = document.getElementById("route-directions");
routeDirections.innerHTML = ''; // 기존 결과 초기화
// 경로 데이터에서 주요 정보 추출 및 표시
if (data.routes && data.routes[0]) {
const route = data.routes[0];
const summary = route.summary;
const sections = route.sections;
// 요약 정보 표시
const distance = summary.distance; // 총 거리 (미터 단위)
const duration = summary.duration; // 예상 소요 시간 (초 단위)
routeDirections.innerHTML += `
<h3>경로 요약</h3>
<p>총 거리: ${(distance / 1000).toFixed(2)} km</p>
<p>예상 소요 시간: ${(duration / 60).toFixed(0)} 분</p>
`;
// 도로 정보 표시
routeDirections.innerHTML += `<h3>도로 정보</h3>`;
sections.forEach(section => {
section.roads.forEach(road => {
routeDirections.innerHTML += `
<p>도로명: ${road.name || '이름 없음'}, 거리: ${road.distance} m, 예상 시간: ${(road.duration / 60).toFixed(0)} 분</p>
`;
});
});
// 길 안내 정보 표시
routeDirections.innerHTML += `<h3>길 안내</h3>`;
sections.forEach(section => {
section.guides.forEach(guide => {
routeDirections.innerHTML += `
<p>${guide.guidance} (${guide.distance} m)</p>
`;
});
});
} else {
routeDirections.innerHTML = '<p>경로를 찾을 수 없습니다.</p>';
}
}
displayRoute
카카오 모빌리티 길찾기 API의 응답 데이터를 받아서, 이를 사용자가 쉽게 이해할 수 있는 형태로 화면에 표시하는 역할
짠 길찾기 완료🧡
1시간 30분 걸려서 다했습니다.
진짜로 이거 뭐야?
나 이번주 두 번 엎었다고 성장했나봐
역시 인간은 힘든 순간이 있어야지 성장한다고
박예슬 API달인이다!
나 오늘 발 뻗고 잘 수 있다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
진짜로 다주거떠
야후야후
'Project > 5V' 카테고리의 다른 글
[3nd Project] 카카오 Api로 주차장 구현하기 10 (11) | 2024.11.19 |
---|---|
[3nd Project]카카오 Api로 주차장 구현하기 9 (1) | 2024.11.17 |
[3nd Project] 카카오 Api로 주차장 구현하기 7 (5) | 2024.11.15 |
[3nd Project] 카카오 Api로 주차장 구현하기 6 (2) | 2024.11.14 |
[3nd Project] 카카오 api로 주차장 구현하기 5 (12) | 2024.11.13 |