Elixir Livebook で衛星データプラットフォーム Tellus から台風情報を取得して地図にプロットする

## はじめに

日本発の衛星データプラットフォーム Tellus を Elixir Livebook から使ってみました

https://www.tellusxdp.com/ja/

以前 Python でやっていたので、 Elixir 版にしようかと

https://qiita.com/RyoWakabayashi/items/8ddc1396062ab270d40a

今回実装したノートブックの全量はこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/tellus/typhoon.livemd

この記事ではゲヒルン株式会社の台風情報APIを使用しています

©Gehirn Inc.

## 実行環境

このリポジトリーの Docker コンテナ上で実行しました

https://github.com/RyoWakabayashi/elixir-learning

## Tellus の使い方

アカウント作成方法はこちら

Tellus OS という、ブラウザ上で地図に衛星データをプロットする方法も説明されています

https://www.tellusxdp.com/ja/howtouse/tellus_os/start_tellus_os.html

ただし、今回私が紹介するのは API 経由でデータを取得する方法です

## 台風情報APIの購入（無料）

Tellus の衛星データは Tellus Market から購入することができます

購入といいつつ、無料で使えるものもたくさんあります

上部メニューの「サービス」->「Tellus Market」をクリックしてください

![スクリーンショット 2022-11-11 17.53.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/68afcad8-9f37-f61d-8f45-02dd27c6ba38.png)

Tellus Market の画面では様々な商品を検索することができます

![スクリーンショット 2022-11-11 17.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/cbd0695b-1da5-bfb6-0294-937b1d88fb6c.png)

今回は台風情報を使うので「台風情報（アーカイブ）」をクリックします

遷移した先にある「購入ページへ」をクリックします

![スクリーンショット 2022-11-11 17.54.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/2dc953cb-dedc-b179-9aae-120ad3a96bf4.png)

必要な項目を記入して、最下部のチェックボックス２つにチェックしてから「購入する」をクリックします

![スクリーンショット 2022-11-11 17.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/3513cf7d-f932-fe2f-12e6-dc19cfb1508f.png)

これで台風情報が使えるようになりました

## トークンの作成

Tellus の API を呼び出すためのトークンを作成します

画面右上のログインユーザー名->「開発環境」をクリックします

![スクリーンショット 2022-11-11 18.03.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b9d8cc19-6ccb-b712-033b-8715de3974ec.png)

「トークンの発行」をクリックすると、新しいトークンが作成され、下に表示されます

![スクリーンショット 2022-11-11 18.03.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/1ec22410-9b11-b73b-d43e-16c7cdbccdcf.png)

これで API を呼ぶ準備ができました

## セットアップ

Livebook を起動してノートブックを開きます

以下のコードをノートブック上で実行してください

```elixir
Mix.install([
  {:httpoison, "~> 1.8"},
  {:json, "~> 1.4"},
  {:kino, "~> 0.8"},
  {:kino_maplibre, "~> 0.1"}
])
```

必要なライブラリをインストールします

- httpoison: REST API を呼び出す
- json: JSON をエンコード、デコードする
- kino: 実行結果を可視化する
- kino_maplibre: 実行結果を地図上に可視化する

以下のコードを実行するとテキストエリアが表示されるので、 Tellus で作っておいたトークンを入力します

```elixir
token_input = Kino.Input.text("Token")
```

台風情報の商品ID（ Tellus の「購入済み」画面から確認できます）を設定しておきます

```elixir
typhoon_product_id = "c34f78fc-3b20-4a0a-a692-c402a0d8cdbe"
```

## Tellus の認証

Tellus の API は、まず自分で発行したトークンと商品IDを認証用 API に送信して、対象商品用の認証トークンを取得します

その後、対象商品用の認証トークンを対象商品の API 呼び出しに使用します

以下のコードで Tellus の認証処理を定義します

```elixir
auth_url = "https://www.tellusxdp.com/api/manager/v2/auth/token/"
json_header = {"Content-Type", "application/json"}

get_product_info = fn product_id ->
  request_body = JSON.encode!(%{product_id: product_id})
  auth_header = {"Authorization", "Bearer " <> Kino.Input.read(token_input)}

  auth_url
  |> HTTPoison.post!(request_body, [auth_header, json_header])
  |> then(&JSON.decode!(&1.body))
end
```

以下のコードを実行すると、台風情報用の認証トークンが取得できます

この認証トークンは一時的なものなので、一定時間経過すると有効期限が切れます

有効期限が切れてエラーが発生した場合はもう一度認証トークンを取得し直してください

```elixir
typhoon_product_info = get_product_info.(typhoon_product_id)
```

![スクリーンショット 2022-11-11 18.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/0127cc5f-e967-8954-f5eb-2c8d61d7e2ef.png)

以下のコードで台風情報取得用の認証ヘッダーを設定します

```elixir
auth_header = {"Authorization", "Bearer " <> typhoon_product_info["token"]}
```

## 台風一覧の取得

以下のコードを実行すると、過去に発生した台風の一覧が取得できます

台風情報 API リファレンスは以下のサイトで公開されています
（各商品の詳細ページに API リファレンスへのリンクがあります）

https://www.tellusxdp.com/market/api_reference/c34f78fc-3b20-4a0a-a692-c402a0d8cdbe?lang=ja&for_customer=true

```elixir
typhoon_events_url = typhoon_product_info["base_url"] <> "/archive/typhoon/events.json"

typhoon_events =
  typhoon_events_url
  |> HTTPoison.get!([auth_header, json_header])
  |> then(&JSON.decode!(&1.body))
```

![スクリーンショット 2022-11-11 18.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f29aae6e-60a5-d1fa-2f3a-a0d2b986bfeb.png)

## 台風情報の取得

個別の台風を指定して、台風の軌跡を取得します

以下のコードで台風情報の取得処理を定義します

```elixir
get_typhoon_points = fn event_id ->
  url = typhoon_product_info["base_url"] <> "/archive/typhoon/" <> event_id <> "_point.json"

  url
  |> HTTPoison.get!([auth_header, json_header])
  |> then(&JSON.decode!(&1.body))
end
```

台風一覧から適当な台風の `eventId` を見つけて指定します

今回は令和３年の台風第８号「ニパルタック」を指定しました

```elixir
typhoon_points = get_typhoon_points.("TC2111")
```

![スクリーンショット 2022-11-11 18.25.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6fa7d17f-879e-1437-37e5-074dbf1ffd8e.png)

## 台風情報の地図へのプロット

取得した台風情報を地図にプロットして、台風の軌道を見てみましょう

地図にプロットできる形に台風情報を整形します

```elixir
marker_list =
  typhoon_points["features"]
  |> Enum.map(fn feature ->
    coordinates = feature["geometry"]["coordinates"]

    %{
      "lat" => Enum.at(coordinates, 1),
      "lng" => Enum.at(coordinates, 0)
    }
  end)
```

![スクリーンショット 2022-11-11 18.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/02bdfacc-6b20-89a0-1e51-123eae70ce95.png)

次のセルを追加するとき、「+Smart」->「Map」を選択してください

Livebook の Smart Cells の機能によって、簡単に地図を表示します

![スクリーンショット 2022-11-11 18.28.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c0f93bf4-8523-9b4e-b977-f7d1db98cae5.png)

![スクリーンショット 2022-11-11 18.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fcfe0ce7-6aa3-38e6-b83e-9dcf6cdd7c23.png)

CENTER に `140, 35` （日本近辺の座標）を入力し、 ZOOM を 3 に設定します

LAYER に適当な名前を入れて、 Source は `marker_list` を選択します

Source の右 Coodinates format に「Two columns」を選択し、 Longtitude に「lng」、 Latitude に「lat」を選択します

Color や Radius 、 Opacity は適当に設定してください 

![スクリーンショット 2022-11-11 18.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fbd63e79-5ebf-7a6d-c457-802b2efe8557.png)

この状態でセルを実行します

![スクリーンショット 2022-11-11 18.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c7681684-ae91-3401-fe2b-b505a17bc191.png)

台風の軌道が表示できました！

## おわりに

Map の Smart Cells の使い方（指定する変数の形式）がいまいち分からず苦労しました

でも Smart Cells だと本当に簡単に地図上で可視化できるのは素晴らしいですね

この方法だと台風の大きさや強さが表せないのが難点ですが、、、

次回は別のデータを可視化してみたいと思います