1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mapbox Isochrone APIを使用して、地図上に到達圏を表示してみた

Last updated at Posted at 2024-05-29

はじめに

手順や完成したコードは公式チュートリアルに沿って、場所を東京駅周辺に変えて試してみました。

Isochrone APIとは

Isochrone APIは指定地点から自動車、自転車、徒歩で指定した移動時間で到達できる範囲を得ることができるAPIです。例えば、東京駅から自動車30分で到達できる場所の範囲を知ることができます。

こういった範囲は到達圏や時間圏などと言われます。

完成イメージ

作成したサンプルは以下になります。
qiita11.gif

コードはトークンを入れれば使えます。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Demo: Get started with the Isochrone API</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- Mapbox GL JS -->
    <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.js"></script>
    <link
      href="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.css"
      rel="stylesheet"
    />
    <!-- Mapbox Assembly -->
    <link
      href="https://api.mapbox.com/mapbox-assembly/v1.3.0/assembly.min.css"
      rel="stylesheet"
    />
    <script src="https://api.mapbox.com/mapbox-assembly/v1.3.0/assembly.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }

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

  <body>
    <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">Choose a travel mode:</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">Walking</div>
          </label>
          <label class="toggle-container">
            <input name="profile" type="radio" value="cycling" checked />
            <div class="toggle toggle--active-null toggle--null">Cycling</div>
          </label>
          <label class="toggle-container">
            <input name="profile" type="radio" value="driving" />
            <div class="toggle toggle--active-null toggle--null">Driving</div>
          </label>
        </div>
        <h4 class="txt-m txt-bold mb6">Choose a maximum duration:</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 min</div>
          </label>
          <label class="toggle-container">
            <input name="duration" type="radio" value="20" />
            <div class="toggle toggle--active-null toggle--null">20 min</div>
          </label>
          <label class="toggle-container">
            <input name="duration" type="radio" value="30" />
            <div class="toggle toggle--active-null toggle--null">30 min</div>
          </label>
        </div>
      </form>
    </div>

    <script>
      mapboxgl.accessToken = 'UserAccessToken';

      const map = new mapboxgl.Map({
        container: 'map', // container id
        style: 'mapbox://styles/mapbox/streets-v12', // stylesheet
        center: [139.767124, 35.681236], // starting position [lng, lat]
        zoom: 11.5 // starting zoom
      });

      // Target the params form in the HTML
      const params = document.getElementById('params');

      // Create variables to use in getIso()
      const urlBase = 'https://api.mapbox.com/isochrone/v1/mapbox/';
      const lon = 139.767124;
      const lat = 35.681236;
      let profile = 'cycling';
      let minutes = 10;

      // Set up a marker that you can use to show the query's coordinates
      const marker = new mapboxgl.Marker({
        'color': '#314ccd'
      });

      // Create a LngLat object to use in the marker initialization
      // https://docs.mapbox.com/mapbox-gl-js/api/#lnglat
      const lngLat = {
        lon: lon,
        lat: lat
      };

      // Create a function that sets up the Isochrone API query then makes a fetch call
      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();
        // Set the 'iso' source's data to what's returned by the API query
        map.getSource('iso').setData(data);
      }

      // When a user changes the value of profile or duration by clicking a button, change the parameter's value and make the API query again
      params.addEventListener('change', (event) => {
        if (event.target.name === 'profile') {
          profile = event.target.value;
        } else if (event.target.name === 'duration') {
          minutes = event.target.value;
        }
        getIso();
      });

      map.on('load', () => {
        // When the map loads, add the source and layer
        map.addSource('iso', {
          type: 'geojson',
          data: {
            'type': 'FeatureCollection',
            'features': []
          }
        });

        map.addLayer(
          {
            'id': 'isoLayer',
            'type': 'fill',
            'source': 'iso',
            'layout': {},
            'paint': {
              'fill-color': '#5a3fc0',
              'fill-opacity': 0.3
            }
          },
          'poi-label'
        );

        // Initialize the marker at the query coordinates
        marker.setLngLat(lngLat).addTo(map);

        // Make the API call
        getIso();
      });
    </script>
  </body>
</html>

作成手順

マップ表示

表示する初期座標を東京駅の座標にしました。

center: [139.767124, 35.681236]

Isochrone APIへのリクエスト

Isochrone APIへリクエストするには、次の3つのパラメータが必要になります。

  • profile:移動する交通手段。walking、cycling、drivingと交通量を考慮したdriving-trafficがオプションとしてあります
  • coordinates:到達圏の中心座標
  • contours_minutes:到達圏を特定するための時間、最大60分まで
https://api.mapbox.com/isochrone/v1/mapbox/{profile}/{coordinates}.json?{contours_minutes}&access_token= <UserAccessToken />

到達圏を描画する

addSourceとaddLayerでisoという名前の空のFeatureCollectionのレイヤーを作成します。APIへのリクエストから返されたGeoJSONの結果をそのままisoにセットします。

map.getSource('iso').setData(data);

map.addSource('iso', {
  type: 'geojson',
  data: {
    'type': 'FeatureCollection',
    'features': []
  }
});

map.addLayer(
  {
    'id': 'isoLayer',
    'type': 'fill',
    'source': 'iso',
    'layout': {},
    'paint': {
      'fill-color': '#5a3fc0',
      'fill-opacity': 0.3
    }
  },
  'poi-label'
);

動的変化を適用する

マップ上に表示する到達圏を左上のサイドバーで指定した移動手段と時間によって変更します。

// Target the "params" form in the HTML portion of your code
const params = document.getElementById('params');

// When a user changes the value of profile or duration by clicking a button, change the parameter's value and make the API query again
params.addEventListener('change', (event) => {
  if (event.target.name === 'profile') {
    profile = event.target.value;
  } else if (event.target.name === 'duration') {
    minutes = event.target.value;
  }
  getIso();
});
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?