OpenLayers入門

## はじめに
この記事は#30DayMapChallenge2022 13日目の記事です。
テーマは5 minute mapです。
OpenLayersを使って背景地図を表示してみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## OpenLayersとは
簡単にダイナミックなマップを設置することができるJavaScriptライブラリ
地図タイル、ベクトルデータ、マーカーを表示することができる
フリーかつオープンソースで、2条項のBSDライセンス（FreeBSDとしても知られています）の下でリリースされている
執筆時の最新バージョンはv7.1.0でした

最近ロゴが変わって可愛くなりました（余談）
他のマップライブラリと比べて、座標系などGISの知識が必要になりますが高機能なことができる印象です。

OpenLayersの利用方法として以下の2つがあります。今回はCDNを使います。
- CDNからインポートする
- npmでインストールする

## 背景地図を表示
OpenStreetMapを表示してみます。（5分で出来たのはここまで・・涙）

```index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>サンプル</title>
        <meta name="description" content="サンプルです" />
        <link href="style.css" rel="stylesheet" />
        <!-- OpenLayers -->
        <script src="https://cdn.jsdelivr.net/npm/ol@v7.1.0/dist/ol.js"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.1.0/ol.css" />
    </head>
    <body>
        <div id="map"></div>
        <script src="main.js"></script>
    </body>
</html>
```

```style.css
body {
    margin: 0;
    padding: 0;
}
#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}
```

```main.js
new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() })],
    view: new ol.View({
        center: [0, 0],
        zoom: 2,
    }),
    target: 'map',
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/099c4f54-aa94-1e01-90d4-c61a9c910afd.png)

背景地図としてOpenStreetMapを表示できました！


## OpenLayersで地理座標系を指定したい
上の状態で中心座標を経度・緯度で設定しても、うまく動作しません。

```main.js
new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() })],
    view: new ol.View({
        center: [139.68786, 35.68355],
        zoom: 6,
    }),
    target: 'map',
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/cd18f17a-420b-b847-3629-a714d93b46c0.png)

東京都を指定したのに、南アフリカに飛ばされてしまいます。
これは座標系の指定によるものです。

OpenLayersでは、明示的に座標系を指定しない場合はWeb メルカトル座標系（EPSG:3857）となります。
地理座標系（経度・緯度）を使う場合は、座標系を地理座標系に変更するか、座標を地理座標系からWebメルカトルに変換する必要がありそうです。

>The projection determines the coordinate system of the center, and its units determine the units of the resolution (projection units per pixel). The default projection is Web Mercator (EPSG:3857).


引用元：[OpenLayers API](https://openlayers.org/en/latest/apidoc/module-ol_View-View.html)

### 座標系を地理座標系に変更する
ViewのプロパティでマップのEPSGコードを地理座標系のものに設定してみます。

```main.js
new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() })],
    view: new ol.View({
        center: [139.68786, 35.68355],
        zoom: 6,
        projection: 'EPSG:4326',
    }),
    target: 'map',
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/df9d6f5b-1517-5bef-00c6-c08f7344d334.png)

経度・緯度で中心座標を日本を指定できました！
ですが、地図がゆがんで見えます。。

### 座標を地理座標系からWebメルカトルに変換する
proj.transformで、変換元のEPSGコード、変換先のEPSGコードを指定することで
Webメルカトル用の座標に変換してみます。

```main.js
new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() })],
    view: new ol.View({
        center: ol.proj.transform([139.68786, 35.68355], 'EPSG:4326', 'EPSG:3857'),
        zoom: 6,
    }),
    target: 'map',
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/aa43e448-cddf-619b-ac39-447f8561392a.png)

こちらだと地図がゆがみません！
OpenLayersは難しい・・

## 参考文献
https://openlayers.org/

https://openlayers.org/doc/tutorials/concepts.html

https://openlayers.org/doc/faq.html