본문 바로가기
API사용

[Mapbox] 등시선API 기초 예시

by 미눅스[멘토] 2025. 4. 25.
728x90

 

 

https://docs.mapbox.com/help/tutorials/get-started-isochrone-api/?step=10

 

Get started with the Isochrone API | Help

Create a web app using the Mapbox Isochrone API that allows users to visualize how far they could walk, bike, or drive within a given amount of time.

docs.mapbox.com

위 URL로 들어가 하나씩 스탭을 밟아보자

하나씩 하면 아래처럼 코드가 나올것이다.

등시선 API는 10만건에 한해서 무료로 사용이 가능하다.

 

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>Get started with the Isochrone API</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <!-- Mapbox GL JS 스크립트 및 스타일시트 불러오기 -->

  <!-- Mapbox Assembly (스타일 유틸리티 프레임워크) 불러오기 -->

  <!-- 지도 및 페이지 스타일 지정 -->
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>

<body>
  <!-- 지도가 렌더링될 div -->
  <div id="map"></div>

  <!-- 사용자 입력 폼: 여행 타입과 시간 선택 -->
  <div class="absolute fl my24 mx24 py24 px24 bg-gray-faint round">
    <form id="params">
      <h4 class="txt-m txt-bold mb6">여행 타입을 선택해 주세요:</h4>
      <div class="mb12 mr12 toggle-group align-center">
        <label class="toggle-container">
          <input name="profile" type="radio" value="walking" />
          <div class="toggle toggle--active-null toggle--null">걷기</div>
        </label>
        <label class="toggle-container">
          <input name="profile" type="radio" value="cycling" checked />
          <div class="toggle toggle--active-null toggle--null">자전거</div>
        </label>
        <label class="toggle-container">
          <input name="profile" type="radio" value="driving" />
          <div class="toggle toggle--active-null toggle--null">자동차</div>
        </label>
      </div>

      <h4 class="txt-m txt-bold mb6">최대 시간을 선택해 주세요:</h4>
      <div class="mb12 mr12 toggle-group align-center">
        <label class="toggle-container">
          <input name="duration" type="radio" value="10" checked />
          <div class="toggle toggle--active-null toggle--null">10분 거리</div>
        </label>
        <label class="toggle-container">
          <input name="duration" type="radio" value="20" />
          <div class="toggle toggle--active-null toggle--null">20분 거리</div>
        </label>
        <label class="toggle-container">
          <input name="duration" type="radio" value="30" />
          <div class="toggle toggle--active-null toggle--null">30분 거리</div>
        </label>
      </div>
    </form>
  </div>

  <script>
    //Mapbox 액세스 토큰 등록 (본인의 토큰으로 교체 가능)
    mapboxgl.accessToken = 'minwooToken';

    // 지도 생성 및 초기 설정
    const map = new mapboxgl.Map({
      container: 'map', // 지도 컨테이너 ID
      style: 'mapbox://styles/mapbox/streets-v12', // 지도 스타일
      center: [-77.0369, 38.895], // 초기 중심 좌표 (워싱턴 D.C.)
      zoom: 11.5 // 초기 줌 레벨
    });

    //Isochrone API 요청에 필요한 기본 변수 설정
    const lon = -77.034; // 중심점 경도
    const lat = 38.899;  // 중심점 위도
    let profile = 'cycling'; // 기본 이동 수단: 자전거
    let minutes = 10;        // 기본 시간: 10분

    //Isochrone API를 호출하는 비동기 함수
    async function getIso() {
      const query = await fetch(
        `${urlBase}${profile}/${lon},${lat}?contours_minutes=${minutes}&polygons=true&access_token=${mapboxgl.accessToken}`,
        { method: 'GET' }
      );
      const data = await query.json(); // 응답 결과 JSON 파싱
      console.log(data); // 콘솔에 결과 출력
      map.getSource('iso').setData(data); // geojson 데이터를 지도 소스에 반영
    }

    //지도 위에 마커 추가
    const marker = new mapboxgl.Marker({
      color: '#314ccd' // 마커 색상 (파란색)
    });

    //Marker 위치를 위한 좌표 객체 (Mapbox는 lng/lat 순서 사용해야 함)
    const lngLat = {
      lon: lon,
      lat: lat
    };

    // 지도 로드 완료 시 실행
    map.on('load', () => {
      // Isochrone GeoJSON 소스 추가
      map.addSource('iso', {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      });

      // Isochrone 레이어 추가
      map.addLayer(
        {
          id: 'isoLayer',
          type: 'fill',
          source: 'iso',
          layout: {},
          paint: {
            'fill-color': '#5a3fc0', // 보라색 계열
            'fill-opacity': 0.3      // 투명도 설정
          }
        },
        'poi-label' //해당 레이어를 이 레이어 아래에 배치
      );

      // API 요청 실행 (초기 표시용)
      getIso();

      // 마커 지도에 표시
      marker.setLngLat([lon, lat]).addTo(map);
    });

    //폼 요소 가져오기
    const params = document.getElementById('params');

    // 사용자가 라디오 버튼 클릭 시 이벤트 감지
    params.addEventListener('change', (event) => {
      // 이동수단이 바뀐 경우
      if (event.target.name === 'profile') {
        console.log(event.target.value);
        profile = event.target.value;
      }
      // 소요 시간이 바뀐 경우
      else if (event.target.name === 'duration') {
        console.log(event.target.value);
        minutes = event.target.value;
      }
      // 값이 바뀌었으므로 다시 API 호출
      getIso();
    });
  </script>
</body>
</html>

 

 

결과는 아래처럼 잘 나온다