MapTilerの地図をReact/Mapbox GL JSを使って最短でブラウザ上に表示させる

<img width="1432" alt="スクリーンショット 2020-01-31 20.03.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/ec54fe0e-3b22-5b62-faaa-baec6d11a759.png">

スイス発のMapTilerに基盤地図情報の建物データなどを盛り込み日本向けにローカライズされた日本地図の配信サービス[MapTiler.JP](https://www.maptiler.jp/)が提供開始になりました。

google mapsなどのサービスと比較して大抵の場合で安価に利用できるので、是非ご利用を検討してみてくださいね！

※[プレスリリース](https://www.value-press.com/pressrelease/235157)
※[紹介記事](https://internet.watch.impress.co.jp/docs/column/chizu3/1232026.html)

フリープランがあるみたいなので早速無料登録して利用してみましょう！

登録は[こちらの記事](https://qiita.com/Yfuruchin/items/77ed96094f6c8645ad8d)を参照

※この記事はmacの方対象ですが、Node.jsとYarnがインストールされていればwinでも動作するとは思います

# Node.jsをインストール

`node -v`コマンドでNode.jsがインストールされているか確認しましょう

```
$node -v
v12.13.1
```

インストールされていない場合は[公式サイト](https://nodejs.org/ja/)から安定版をインストール！

# Yarnのインストール

`yarn -v`コマンドでYarnがインストールされているか確認しましょう

```
$yarn -v
1.21.0
```

インストールされていない場合は以下のコマンドでインストール

```
$brew install yarn
```

# creat-react-appのインストール

以下のコマンドでインストール

```
$yarn global add create-react-app
```

# Reactプロジェクトの作成

以下コマンドでReactのプロジェクトを作成
※maptiler_appの部分は任意です

```
$npx create-react-app maptiler_app
```

作成したプロジェクトに移動、サーバーを起動させます

```
$cd maptiler_app
$yarn start
```

[http://localhost:3000](http://localhost:3000)にアクセスし、以下のような画面が表示されればReactの準備は完了です

<img width="1440" alt="スクリーンショット 2020-01-31 21.04.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/37f7aa05-99a6-0144-eec3-f870447e6366.png">

## Mapbox GL JSのインストール

Mapbox GL JSは以下のコマンドで簡単にインストールすることができます。

```
$yarn add mapbox-gl
```

# 背景地図を読み込む準備をする

登録したMapTiler.jpのトップページからマイページに飛び…

<img width="1440" alt="スクリーンショット 2020-02-02 17.03.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/ed5cad97-385a-0673-f576-68bf9dcc13df.png">

左側のメニューバーの「Maps」を選択し…


<img width="1440" alt="スクリーンショット 2020-02-02 17.04.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/564c43d8-66fc-666e-6bc1-16ad485cad7a.png">

下の方に移動すると「JP MIERUNE Streets」という項目があるのでクリック！

<img width="1440" alt="スクリーンショット 2020-02-02 17.04.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/3ac62e8b-680f-351c-49e2-c56f97823729.png">

「JP MIERUNE Streets」の画面で、背景地図のイメージが確認できます！

<img width="1207" alt="スクリーンショット 2020-02-02 17.08.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/ac2a92bf-68e3-9463-70ff-002d1699a715.png">

下に移動し、「Use vector style」に書いてあるURLを利用して地図を表示させますのでどこかにメモしておきましょう！

<img width="947" alt="スクリーンショット 2020-02-02 17.10.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/802e878e-59f1-fdf4-1431-a7af4db51f4f.png">

URLは

```
https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=hogehogefugafuga
```

のようになっており、`hogehogefugafuga`の部分はアカウントごとに異なる大切なキーですので、公開などしないようにしておきましょう！

とはいえ、クエリパラメータとしてkeyを設定しているため、デベロッパーツールなどからkeyが覗けるので、実運用する際にはリファラーを切るなど自己管理を徹底しましょう！

# プロジェクトの設定

現在のプロジェクト構造はこんな感じになっていると思います

<img width="288" alt="スクリーンショット 2020-01-31 21.14.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/b3688fcb-7da1-aea4-cc62-83a2ad25d49a.png">

`src/App.js`を内のコードを削除して以下のように書き換えましょう

```src/App.js
import React, {Component} from 'react';
import './App.css'
//mapbox gl jsとcss呼び出し
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
//APIキーの読み込み
import keyJson from './key';

const maptilerKey = keyJson["maptilerKey"]


class App extends Component {
    // DOMが出来上がっているcomponentDidMount以降のライフサイクルでmapオブジェクトをインスタンス化
    componentDidMount() {
        let map = new mapboxgl.Map({
            container: this.container,
            style: `https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=${maptilerKey}`,
            center: [141.350755, 43.068661],
            zoom: 13
        });
        //マップのコントローラー追加
        map.addControl(new mapboxgl.NavigationControl());
    }

    render() {
        return (
            <dev className={"map"} ref={e => (this.container = e)}/>
        )
    }
}

export default App;
```

その後、srcディレクトリ内(App.jsと同ディレクトリ)にkey.jsonというファイルを作成し、先ほどメモしておいたURLのキーの部分をコピーしましょう

```src/key.json
{
    "maptilerKey": "hogehogefugafuga"
}
```

## App.jsの細部の説明

書いてあるコードの説明をします！

以下ではMapbox GL JSを読み込んでいます。

```src/App.js
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
```

作成したkey.jsonはApp.jsでは以下のように読み込みます

```src/App.js
import keyJson from './key';

const maptilerKey = keyJson["maptilerKey"]
```

以下の部分ではMapbox GL JSを利用して地図を表示させています。

react/Mapbox GL JSで背景地図を読み込む場合は、DOMが生成されている`componentDidMount`以降のライフサイクルでmapオブジェクトをインスタンス化させる必要があるようで、以下のようなコードになっています。

右記の記事を参考にさせていただきました！：[React と Mapbox GL JS を使ってベクトルタイルを表示する](https://qiita.com/KamataRyo/items/f3e59d61ca19d61e31e8)

```src/App.js
class App extends Component {
    // DOMが出来上がっているcomponentDidMount以降のライフサイクルでmapオブジェクトをインスタンス化
    componentDidMount() {
        let map = new mapboxgl.Map({
            container: this.container,
            style: `https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=${maptilerKey}`,
            center: [141.350755, 43.068661],
            zoom: 13
        });
        //マップのコントローラー追加
        map.addControl(new mapboxgl.NavigationControl());
    }

    render() {
        return (
            <div className={"map"} ref={e => (this.container = e)}/>
        )
    }
}
```

```src/App.js
        //マップのコントローラー追加
        map.addControl(new mapboxgl.NavigationControl());
```

の部分ではwebサービスで地図が表示されている箇所によく見るこれ
<img width="62" alt="スクリーンショット 2020-02-02 18.04.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/794ae2d0-3c9d-92c4-6749-087906b1c865.png">
を表示させるためのコンポーネントを読み込んでいます

最後に、このファイルのデフォルトでAppクラスを吐き出すように設定します。

```
export default App;
```

## App.cssを編集

App.cssを以下のように編集し、地図を画面いっぱいまで広げましょう！

```src/App.css
.map {
    width: 100vw;
    height: 100vh;
}
```

# 地図をブラウザ上で確認！

全ての設定が終わったので以下のコマンドでサーバーを起動させブラウザで[localhost:3000](http://localhost:3000/)にアクセスしましょう！

こんな感じの画面が表示されれば成功です！

ベクターの地図をMapbox GL JSで読み込んでいるので、斜めから見ても回転させても文字がしっかり崩れずに表示されていますね！

![maptiler.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/67da61d5-1e3c-33dd-38a2-26d288ad1e13.gif)

よくできました！！！