728x90
https://docs.mapbox.com/help/tutorials/getting-started-directions-api/?step=0
Getting started with the Mapbox Directions API | Help
Add routing capabilities to your application with the Mapbox Directions API.
docs.mapbox.com
위 URL로 접속하면 길찾기 예시를 확인할 수 있다.
*월 10만건에 대해 무료로 제공한다.
접속해서 설명서대로 단계를 한개씩 밟아보자.
설명하기 너무 길어 VsCode로 복붙 후 눈으로 확인하자
설명은 주석으로 달아놓았다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>Mapbox Directions API - 경로 찾기 예제</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#instructions {
position: absolute;
margin: 20px;
width: 25%;
top: 0;
bottom: 20%;
padding: 20px;
background-color: #fff;
overflow-y: scroll;
font-family: sans-serif;
}
</style>
</head>
<body>
<!-- 지도 표시할 영역 -->
<div id="map"></div>
<!-- 경로 안내 표시할 영역 -->
<div id="instructions"></div>
<script>
// Mapbox 액세스 토큰 설정
mapboxgl.accessToken = ' minwooToken' ;
// 지도 객체 생성
const map = new mapboxgl.Map({
container: 'map', // 지도를 표시할 div ID
style: 'mapbox://styles/mapbox/streets-v12', // 지도 스타일
center: [126.735901, 37.348980], // 초기 중심 좌표 (경도, 위도)
zoom: 12 // 초기 확대 레벨
});
// 출발 지점 좌표 (고정)
const start = [126.735901, 37.348980];
/**
* 도착 지점을 받아 경로를 요청하고 지도에 표시하는 함수
* @param {Array} end 도착 지점 좌표 [lng, lat]
*/
async function getRoute(end) {
// Directions API를 호출하여 경로 데이터 가져오기
const query = await fetch(
`https://api.mapbox.com/directions/v5/mapbox/cycling/${start[0]},${start[1]};${end[0]},${end[1]}?steps=true&geometries=geojson&language=ko&access_token=${mapboxgl.accessToken}`
);
const json = await query.json();
const data = json.routes[0]; // 첫 번째 경로 정보 가져오기
const route = data.geometry; // 경로의 GeoJSON 데이터
// GeoJSON 형식으로 경로 데이터 생성
const geojson = {
'type': 'Feature',
'properties': {},
'geometry': route
};
// 만약 기존에 'route' 소스가 있으면 데이터 업데이트
if (map.getSource('route')) {
map.getSource('route').setData(geojson);
}
// 없으면 새로 'route' 레이어 추가
else {
map.addLayer({
id: 'route',
type: 'line',
source: {
type: 'geojson',
data: geojson
},
layout: {
'line-join': 'round', // 선을 부드럽게 연결
'line-cap': 'round' // 선 끝을 둥글게
},
paint: {
'line-color': '#3887be', // 선 색상
'line-width': 5, // 선 굵기
'line-opacity': 0.75 // 선 투명도
}
});
}
// 경로 안내(instructions) 영역 업데이트
const instructions = document.getElementById('instructions');
const steps = data.legs[0].steps; // 단계별 안내 정보
let tripInstructions = '';
for (const step of steps) {
tripInstructions += `<li>${step.maneuver.instruction}</li>`; // 각각 안내 문구 추가
}
// 경로 안내 HTML 작성
instructions.innerHTML = `
<p id="prompt">📍 지도를 클릭하면 다른 도착지까지 경로를 찾을 수 있습니다.</p>
<p><strong>예상 소요 시간: ${Math.floor(data.duration / 60)}분 🚴</strong></p>
<ol>${tripInstructions}</ol>
`;
}
// 지도 로드 완료 시
map.on('load', () => {
// 기본 도착 지점 설정
const defaultEnd = [126.740000, 37.355000];
// 출발 지점을 지도에 원(circle)으로 표시
map.addLayer({
'id': 'origin-circle',
'type': 'circle',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': start
}
}
]
}
},
'paint': {
'circle-radius': 10, // 원 크기
'circle-color': '#4ce05b' // 원 색상 (초록색)
}
});
// 도착 지점을 지도에 원(circle)으로 표시
map.addLayer({
'id': 'destination-circle',
'type': 'circle',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': defaultEnd
}
}
]
}
},
'paint': {
'circle-radius': 10, // 원 크기
'circle-color': '#f30' // 원 색상 (빨간색)
}
});
// 기본 경로 요청 및 표시
getRoute(defaultEnd);
});
// 지도 클릭 시 이벤트 처리
map.on('click', (event) => {
// 클릭한 좌표 가져오기
const coords = Object.keys(event.lngLat).map(
(key) => event.lngLat[key]
);
// 클릭한 위치를 도착지로 설정
const end = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': coords
}
}
]
};
// 도착지 데이터 업데이트
map.getSource('destination-circle').setData(end);
// 새 경로 요청
getRoute(coords);
});
</script>
</body>
</html>
이렇게 시작점, 도착점의 길과 예상 소요시간 및 순서까지 잘 나오는것을 확인
자전거 애니메이션 추가버전
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>Mapbox Directions API - 경로 찾기 예제</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#instructions {
position: absolute;
margin: 20px;
width: 25%;
top: 0;
bottom: 20%;
padding: 20px;
background-color: #fff;
overflow-y: scroll;
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="instructions"></div>
<script>
mapboxgl.accessToken = 'minwooToken';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [126.735901, 37.348980],
zoom: 12
});
const start = [126.735901, 37.348980];
let marker;
let animationFrameId;
//두 좌표 사이를 선형 보간(interpolate)
function interpolate(p1, p2, t) {
const lng = p1[0] + (p2[0] - p1[0]) * t;
const lat = p1[1] + (p2[1] - p1[1]) * t;
return [lng, lat];
}
//경로 따라 자전거 아이콘 부드럽게 애니메이션
function animateRoute(coordinates) {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
if (marker) {
marker.remove();
}
const bikeIcon = document.createElement('div');
bikeIcon.innerHTML = '🚴';
bikeIcon.style.fontSize = '24px';
bikeIcon.style.transform = 'translate(-50%, -50%)';
marker = new mapboxgl.Marker(bikeIcon)
.setLngLat(coordinates[0])
.addTo(map);
let progress = 0;
const speed = 0.01; // ★ 속도 설정 (0.001 ~ 0.003 추천)
function moveMarker() {
const n = coordinates.length;
const currentIndex = Math.floor(progress);
const nextIndex = currentIndex + 1;
if (nextIndex >= n) return; // 경로 끝 도달
const t = progress - currentIndex;
const currentCoord = coordinates[currentIndex];
const nextCoord = coordinates[nextIndex];
const interpolatedCoord = interpolate(currentCoord, nextCoord, t);
marker.setLngLat(interpolatedCoord);
progress += speed;
animationFrameId = requestAnimationFrame(moveMarker);
}
moveMarker();
}
//도착 지점을 받아 경로를 요청하고 지도에 표시하는 함수
async function getRoute(end) {
const query = await fetch(
`https://api.mapbox.com/directions/v5/mapbox/cycling/${start[0]},${start[1]};${end[0]},${end[1]}?steps=true&geometries=geojson&language=ko&access_token=${mapboxgl.accessToken}`
);
const json = await query.json();
const data = json.routes[0];
const route = data.geometry;
const geojson = {
'type': 'Feature',
'properties': {},
'geometry': route
};
if (map.getSource('route')) {
map.getSource('route').setData(geojson);
} else {
map.addLayer({
id: 'route',
type: 'line',
source: {
type: 'geojson',
data: geojson
},
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#3887be',
'line-width': 5,
'line-opacity': 0.75
}
});
}
const instructions = document.getElementById('instructions');
const steps = data.legs[0].steps;
let tripInstructions = '';
for (const step of steps) {
tripInstructions += `<li>${step.maneuver.instruction}</li>`;
}
instructions.innerHTML = `
<p id="prompt">📍지도를 클릭하면 다른 도착지까지 경로를 찾을 수 있습니다.</p>
<p><strong>예상 소요 시간: ${Math.floor(data.duration / 60)}분 🚴</strong></p>
<ol>${tripInstructions}</ol>
`;
//경로 따라 부드러운 자전거 애니메이션 시작
animateRoute(route.coordinates);
}
map.on('load', () => {
const defaultEnd = [126.740000, 37.355000];
map.addLayer({
'id': 'origin-circle',
'type': 'circle',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': start
}
}
]
}
},
'paint': {
'circle-radius': 10,
'circle-color': '#4ce05b'
}
});
map.addLayer({
'id': 'destination-circle',
'type': 'circle',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': defaultEnd
}
}
]
}
},
'paint': {
'circle-radius': 10,
'circle-color': '#f30'
}
});
getRoute(defaultEnd);
});
map.on('click', (event) => {
const coords = Object.keys(event.lngLat).map(
(key) => event.lngLat[key]
);
const end = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Point',
'coordinates': coords
}
}
]
};
map.getSource('destination-circle').setData(end);
getRoute(coords);
});
</script>
</body>
</html>
'API사용' 카테고리의 다른 글
[Mapbox] 등시선API 기초 예시 (1) | 2025.04.25 |
---|---|
[Mapbox] 한국 지적도 geoJSON파일 만들기 (1) | 2025.04.03 |
[Mapbox] 맵 박스에 행정안전구역 범죄주의구간 표시하기 (0) | 2025.03.21 |
[Mapbox] 맵 박스 지도 위성사진으로 교체하기 (0) | 2025.03.14 |
[Mapbox] 맵 박스 눈/비 내리는 효과 예제 (0) | 2025.03.13 |