ReactでLeafletとMapbox GL JSとOpenLayersの開発環境を構築してみた

![try-044_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/7c104a3e-0b14-3b7f-7d9e-2953ed24efbd.gif)

<br>

![react.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/ea0976de-3db3-8363-7f63-09159dd47013.png)

![leaflet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/67729a2c-aebe-b7c1-eba3-c43e93fa6181.png)

![mapboxgljs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/ac9af97c-ba16-82ae-e0fe-38e32427088e.png)

![openlayers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/02ab5b41-bf1c-7b64-25b9-d30edefb11c0.png)

<br>

### ReactでLeafletとMapbox GL JSとOpenLayersの開発環境を構築してみました :tada:  

ReactでLeafletとMapbox GL JSとOpenLayersを利用する時に、ライブラリを直接読み込んでいるかたもいると思いますが、今回はReact向けのラッパーライブラリを利用して開発環境を構築してみました！

<br>

## 1. 事前準備

- Reactの環境準備  
    - [React #002 – TypeScript環境構築](https://day-journal.com/memo/react-002/)
    - node v14.8.0
    - npm v6.14.8
    - React v16.13.1
    - TypeScript v3.7.5

<br>

## 2. 共通設定

#### tsconfig.json

```json
{
    "compilerOptions": {
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react",
        // 暗黙のany型をエラーにしない
        "noImplicitAny": false
    },
    "include": ["src"]
}
```

ライブラリがうまく動作しないので、今回は暗黙のany型をエラーにしない設定をします。

```json
// 暗黙のany型をエラーにしない
"noImplicitAny": false
```

<br>

/src

#### index.tsx

```tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import MapPane from './MapPane';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
    <React.StrictMode>
        <App />
        <MapPane />
    </React.StrictMode>,
    document.getElementById('root')
);

serviceWorker.unregister();
```

新規作成する「MapPane.tsx」を、「index.tsx」で読み込みます。

```tsx
import MapPane from './MapPane';

<MapPane />
```

<br>

## 3. 各ライブラリ設定

### React x Leaflet

ReactとLeafletの組み合わせの場合は、「[react-leaflet](https://github.com/PaulLeCam/react-leaflet)」を利用します。

<br>

ライブラリをインストールします。

```shell

npm install leaflet
npm install react-leaflet
npm install @types/leaflet
npm install @types/react-leaflet
```

<br>

次に、地図を表示させるためのコードを書きます。今回は、「MapPane.tsx」と「MapPane.css」を作成します。  

![try-044_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/7b84e0bb-cb8e-9e73-7ded-627ce395594e.png)

/src

#### MapPane.tsx

```tsx
import React from 'react';
// react-leaflet読み込み
import { Map, TileLayer } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import './MapPane.css';

export default function MapPane() {
    return (
        // マップ設定
        <Map className="MapPane" center={[35.681, 139.767]} zoom={14}>
            <TileLayer
                attribution='<a href="https://maptiler.jp/" target="_blank">© MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>'
                url="https://api.maptiler.com/maps/jp-mierune-streets/256/{z}/{x}/{y}.png?key=[APIキー]"
            />
        </Map>
    );
}
```

Leaflet関係のライブラリを読み込みます。

```tsx
// react-leaflet読み込み
import { Map, TileLayer } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
```

背景地図を表示します。

```tsx
// マップ設定
<Map className="MapPane" center={[35.681, 139.767]} zoom={14}>
    <TileLayer
        attribution='<a href="https://maptiler.jp/" target="_blank">© MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>'
        url="https://api.maptiler.com/maps/jp-mierune-streets/256/{z}/{x}/{y}.png?key=[APIキー]"
    />
</Map>
```

<br>

/src

#### MapPane.css

```css
.MapPane {
    z-index: 0;
    height: 1000px;
    text-align: left;
}
```

<br>

ローカルサーバーで確認

```shell
npm start
```

<br>
       
ローカルサーバーを立ち上げると、マップが表示されます。

![try-044_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/d2c18117-980f-cac4-5ac7-4f8d5c26f337.gif)

<br>

### React x Mapbox GL JS

ReactとMapbox GL JSの組み合わせの場合は、「[react-map-gl](https://github.com/visgl/react-map-gl)」を利用します。

<br>

ライブラリをインストールします。

```shell
npm install react-map-gl
npm install @types/react-map-gl
```

<br>

次に、地図を表示させるためのコードを書きます。今回は、「MapPane.tsx」を作成します。  

![try-044_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/75053ed0-d335-2588-7c4b-160fd1e3fda0.png)

<br>

/src

#### MapPane.tsx

```tsx
import React from 'react';
import { useState } from 'react';
// react-map-gl読み込み
import ReactMapGL from 'react-map-gl';

export default function MapPane() {
    // オプション設定
    const [viewport, setViewport] = useState({
        latitude: 35.681,
        longitude: 139.767,
        zoom: 13,
        bearing: 0,
        pitch: 0,
    });

    return (
        // マップ設定
        <ReactMapGL
            {...viewport}
            width="100%"
            height="1000px"
            mapStyle="https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=[APIキー]"
            onViewportChange={(nextViewport) => setViewport(nextViewport)}
        />
    );
}
```

Mapbox GL JS関係のライブラリを読み込みます。

```tsx
// react-map-gl読み込み
import ReactMapGL from 'react-map-gl';
```

オプションを設定します。

```tsx
// オプション設定
const [viewport, setViewport] = useState({
    latitude: 35.681,
    longitude: 139.767,
    zoom: 13,
    bearing: 0,
    pitch: 0,
});
```

背景地図を表示します。

```tsx
// マップ設定
<ReactMapGL
    {...viewport}
    width="100%"
    height="1000px"
    mapStyle="https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=[APIキー]"
    onViewportChange={(nextViewport) => setViewport(nextViewport)}
/>
```

<br>

ローカルサーバーで確認

```shell
npm start
```

<br>

ローカルサーバーを立ち上げると、マップが表示されます。

![try-044_02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/5c33ccab-e127-c2d6-4b29-3330c844dac9.gif)

<br>

### React x OpenLayers

ReactとOpenLayersの組み合わせの場合は、「[react-openlayers](https://github.com/allenhwkim/react-openlayers)」を利用します。

<br>

ライブラリをインストールします。

```shell
npm install react-openlayers
```

<br>

次に、地図を表示させるためのコードを書きます。今回は、「MapPane.tsx」と「MapPane.css」を作成します。  

![try-044_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/209156e8-f2c4-d919-1f3c-e28d3cc4af85.png)

<br>

/src

#### MapPane.tsx

```tsx
import React from 'react';
// react-openlayers読み込み
import { layer, control, Controls, Map, Layers } from 'react-openlayers';
import './MapPane.css';

export default function MapPane() {
    return (
        // マップ設定
        <Map
            className="MapPane"
            view={{
                center: [15558836.760364894, 4256835.08019988],
                zoom: 14,
            }}
        >
            <Layers>
                <layer.Tile />
            </Layers>
            <Controls attribution={true}>
                <control.Zoom />
            </Controls>
        </Map>
    );
}
```

OpenLayers関係のライブラリを読み込みます。

```tsx
// react-openlayers読み込み
import { layer, control, Controls, Map, Layers } from 'react-openlayers';
```

背景地図を表示します。

```tsx
// マップ設定
<Map
    className="MapPane"
    view={{
        center: [15558836.760364894, 4256835.08019988],
        zoom: 14,
    }}
>
    <Layers>
        <layer.Tile />
    </Layers>
    <Controls attribution={true}>
        <control.Zoom />
    </Controls>
</Map>
```

<br>

/src

#### MapPane.css

```css
.openlayers-map {
    z-index: 0;
    height: 1000px;
    text-align: left;
}
```

<br>

ローカルサーバーで確認

```shell
npm start
```

<br>

ローカルサーバーを立ち上げると、マップが表示されます。

![try-044_03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60444/2cfab568-7d45-71f6-ce21-188553f30ad1.gif)

<br>

#### Reactとreact-leaflet・react-map-gl・react-openlayersを利用することで、手軽にReactで各マップライブラリの開発環境の構築ができました :thumbsup: 

各マップライブラリを、直接読み込んで利用することもできますが、ラッパーライブラリを利用することである程度は手軽に操作ができると思います。ただ、用途により直接読み込むかラッパーライブラリを利用するかの選択は必要となりそうです :bulb:

#### お好きなマップライブラリでゼヒ試してみてください！

<br>

React・Leaflet・Mapbox GL JS・OpenLayersについて、他にも記事を書いています。よろしければぜひ :bow:
<a href="https://day-journal.com/memo/tags/React" target="_blank">tags - React</a>
<a href="https://day-journal.com/memo/tags/Leaflet" target="_blank">tags - Leaflet</a>
<a href="https://day-journal.com/memo/tags/MapboxGLJS" target="_blank">tags - Mapbox GL JS</a>
<a href="https://day-journal.com/memo/tags/OpenLayers" target="_blank">tags - OpenLayers</a>

<br>
<br>

<a href="https://dayjournal.booth.pm" target="_blank"><img src="https://day-journal.com/memo/images/etc/book.png" alt="book"></a>