台風の経路と勢力を眺める２（ベストトラック）

## はじめに
先日、以下の記事で、2001年以降の台風位置表 CSV を用いて、台風の位置と勢力の関係を概観してみました。

https://qiita.com/mg_kudo/items/7c7d5dfc3685a9333079

一方、2001年より前の台風データについては、気象庁から「ベストトラック（Best Track）」というデータで提供されています。今回は、こちらのデータを用いて、1951年～2023年現在までの台風の位置と勢力について、見てみたいと思います。

## データの入手と加工
気象庁の以下のページでデータを入手可能です。

https://www.jma.go.jp/jma/jma-eng/jma-center/rsmc-hp-pub-eg/besttrack.html

1951年～現在（2023年）までの台風データがひとつのテキストファイルにまとまっています。一方、[2001年以降の台風位置表 CSV](https://www.data.jma.go.jp/yoho/typhoon/position_table/index.html) とは異なり、整然データとはなっておりません。

データフォーマットについては、以下のページに掲載されています。

https://www.jma.go.jp/jma/jma-eng/jma-center/rsmc-hp-pub-eg/Besttracks/e_format_bst.html

簡単に言うと、各台風の情報（台風番号や名称など）を記載した行の後ろに、その台風の各位置における情報（経度、緯度、中心気圧など）が、1つの位置につき1行掲載されています。位置の情報だけ見れば整然データとなっています。以下はイメージです。

```
台風の情報
位置の情報
位置の情報
・・・
位置の情報
台風の情報
位置の情報
位置の情報
・・・
位置の情報
・・・
```

ただし、各行について、タブやコンマといった区切り文字があるわけではなく、厳密に各情報が記載される文字の位置が決まっています。たとえば、以下の各台風の情報となりますが、台風の名称は `HHHHHHHHHHHHHHHHHHHH` で記載された31文字目～50文字目に記載されています。各情報は空白を含む場合の他、空白だけの場合もありえるので、スペースなど（正規表現では `\s`）で区切る手法は使うことができないです。

なお、各台風の情報の、先頭の `AAAAA` は固定で `66666` となっていますので、この部分を使って、台風毎の情報か、各位置の情報かを識別することになりそうです。

```:各台風の情報
    5    10   15   20   25   30   35   40   45   50   55   60   65   70   75   80
::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|
AAAAA BBBB  CCC DDDD EEEE F G HHHHHHHHHHHHHHHHHHHH              IIIIIIII
```
```:各位置における情報
    5    10   15   20   25   30   35   40   45   50   55   60   65   70   75   80
::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|::::+::::|
AAAAAAAA BBB C DDD EEEE FFFF     GGG     HIIII JJJJ KLLLL MMMM         P
```

今回、今後の解析をしやすくするために、各台風の情報（台風番号や名称）を取り出して、各位置の情報に付与して、整然データとなっている CSV を作成しました。各情報について、JavaScript を用いた正規表現で取り出すことします。正規表現は以下の通りです。

```JavaScript
// 変数 line は各行の文字列とする。
// 台風毎の情報
const m = line.match(/^66666 (.{4})  (.{3}) (.{4}) (.{4}) (.) (.) (.{20})              (.{8})/);
// 各位置の情報
const c = line.match(/^(.{8}) (.{3}) (.) (.{3}) (.{4}) (.{4})     (.{3})     (.)(.{4}) (.{4}) (.)(.{4}) (.{4})         (.)/);
```

ベストトラックデータから情報を取り出し、整然データ CSV として保存するコード全体は以下のようになります。

```JavaScript
const fs = require('fs');
// ベストトラック（"bst_all.txt"）のデータを読み込み
const text = fs.readFileSync("bst_all.txt", "utf-8");
let csv = "台風識別,日時,緯度,経度,中心気圧,最大風速,50kt長径方向,50kt長径,50kt短径,30kt長径方向,30kt長径,30kt短径,上陸"
        + "\n";
let tInfo = "";
text.split(/\n/).forEach( line => {
  if(!line) return;
  if(!line.match(/\d/)) return;
  if(line.match(/^66666/)){
    const m = line.match(/^66666 (.{4})  (.{3}) (.{4}) (.{4}) (.) (.) (.{20})              (.{8})/);
    const yy = m[1].slice(0,2);
    const tt = m[1].slice(2,4);
    let year = (yy>50) ? "19" + yy : "20" + yy;
    // "{年(yyyy)}T{台風番号}_{国際名}" 形式で識別子とする
    tInfo = year + "T" + tt + "_" + m[7].replace(/\s+/, "");
    return; 
  }
  const c = line.match(/^(.{8}) (.{3}) (.) (.{3}) (.{4}) (.{4})     (.{3})     (.)(.{4}) (.{4}) (.)(.{4}) (.{4})         (.)/);
  if(c){
    csv += `${tInfo},${c[1]},${c[4]/10},${c[5]/10},${c[6]},${c[7]},${c[8]},${c[9]},${c[10]},${c[11]},${c[12]},${c[13]},${c[14]}` + "\n";
  }
});
fs.writeFile(`./tyhoon-bst.csv`, csv, (e) => {
  if(e) console.error(e);
});
```

なお、JavaScriptでこれらのデータを処理する場合、`slice()` の方が高速かつデータ提供者の意図に合っているかもしれませんが、正規表現の処理でもそんなに時間はかからなかったので、このまま進めました。

## データの観察

提供されているデータフォーマットを整然データとするまでの処理が異なりましたが、これ以降の作業は、[前回の記事](https://qiita.com/mg_kudo/items/7c7d5dfc3685a9333079)とは大きく変わりませんので、前回行った内容から、位置（経緯度）と勢力（中心気圧）にポイントを絞って見ていきたいと思います。

:::note warn
各位置の情報として、1951年であっても、経度・緯度、中心気圧は提供されていますが、最大風速や上陸の有無のフラグといった情報は、どうやら途中から追加されているようです。たとえば、上陸フラグは1991年以降のデータにしか見られません。これらの情報がいつから追加されているのかは、気象庁の Web ページでは見つけることができていません。
:::

まずは、経緯度と中心気圧をプロットしてみます。ツールは、R を用いています。

```R
# 整然データへ変換した CSV （"tyhoon-bst.csv"）の読み込み
tdf <- read.csv("tyhoon-bst.csv", header=TRUE)
pairs(tdf[,c(3,4,5)], panel = panel.smooth)
```
傾向は、2001年以降と大きくは変わらないような印象です。
![ベストトラック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/b0bd1fb7-0b5d-e74b-988e-ac5ecc8283b7.png)

次に、緯度と中心気圧について、詳しく見てみます。

```R
plot(tdf$緯度, tdf$中心気圧, col=1, type = "p", main="緯度と中心気圧の関係")
abline(v=35.5, col="red") #東京湾
abline(v=33.5, col="red", lty=2) #紀伊半島
abline(v=31, col="red", lty=2) #大隅半島
abline(v=30, col="red") #30度
abline(v=26.2, col="red", lty=2) #那覇市
abline(h=911.8, col="red") #室戸台風
abline(h=929.6, col="red") #伊勢湾台風
abline(h=940, col="red", lty=2) #中心気圧 940 hPa
abline(h=965, col="red", lty=2) #中心気圧 965 hPa
```
![緯度と中心気圧の関係.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/180a0e44-2837-7bed-5556-4fa77f469f94.png)

2001年以降の台風でも注目していた「プロットがされていない領域」ですが、今回も東京湾相当の緯度より北においては、約940 hPa 以下の台風がプロットがされていません。そのため、**1951年以降、東京湾に相当する緯度帯に伊勢湾台風級（約930 hPa）の経験はない**ということが分かります。（なお、前記事からの繰り返しになりますが、**今後も来ないとは言っていない**です。）

紀伊半島周辺の緯度帯ですと、930 hPa 以下のプロットも見られます。

なお、中心気圧 940 hPa くらいになると、高緯度でもプロットが見られます。以下は、北緯30度より北において、930 hPa 以下、940 hPa 以下となった位置をプロットしたものです。

* 930 hPa 以下となった位置
![北緯30度-930hPa以下.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/b38db268-2d17-d57e-1dd3-b4786180d93f.png)
* 940 hPa 以下となった位置
![北緯30度-940hPa以下.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/486ffa30-f195-441d-cf2c-03c44fa313ca.png)


## 台風経路を地図上でプロット

[前回の記事](https://qiita.com/mg_kudo/items/7c7d5dfc3685a9333079)と同様に今回も、データを GeoJSON へ変換し、ウェブ地図上で見ることができるようにしています。

https://mghs15.github.io/typhoon-besttrack-overview/


（**追記**）
経路だけでなく、各位置の情報もポイントデータとして表示できるようにしました。点の色を中心気圧によって変えています。また、中心気圧で絞り込みをできるようにしています。以下は、東京周辺で 965 hPa 以下となった地点を絞り込んだ例です。

![各位置の情報（965hPa以下で絞り込み）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/9e1d3e92-1e5f-95e4-cbee-4ecea559165d.png)
各位置の情報は、経路のラインデータと比べてデータ量が非常に大きくなります。そのため、そのまま GeoJSON データとして配信するのは避け、ベクトルタイルとしています。ホストする際は、[PMTiles](https://github.com/protomaps/PMTiles/) として、１つのファイルをサーバ（GitHub レポジトリ）へアップロードすれば良いようにしています。便利です。

* 全台風経路の表示例
![ベストトラック全データ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/0388ed92-fba9-f702-1e11-fe1407f15c9b.png)
* 1951年以降の各年の台風1号の表示例
![1951～各年台風1号.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/685b4fb6-c3e0-e0b0-90a1-474a5554d7d2.png)

## ランキング

各台風の中心気圧の最小値を並べてみました。

トップにランクインした[昭和54年台風第20号](https://www.data.jma.go.jp/obd/stats/data/bosai/report/1979/19791010/19791010.html)は、観測史上世界で最も低い気圧となっているようです。気象庁によれば、全国各地で暴風が吹き、北海道の東部では漁船の遭難が相次ぎ、67名の死者・行方不明者が出たとのことです。

4位は昭和33年の[狩野川台風](https://www.data.jma.go.jp/obd/stats/data/bosai/report/1958/19580926/19580926.html)です。気象庁によれば、北緯30度線を越えたあたりから急速に衰えたため、風による被害は少なかったとのことですが、伊豆半島中部では、特に集中して雨が降り、大量の水が流れ込んだ狩野川が氾濫、伊豆地方だけで1,000名を超える死者が出ました。 

|行ラベル	|最小 / 中心気圧|
|:---:|:---:|
|1979T20_TIP	|870|
|1973T15_NORA	|875|
|1975T20_JUNE	|875|
|1958T22_IDA	|877|
|1966T04_KIT	|880|
|1978T26_RITA	|880|
|1984T22_VANESSA	|880|

先ほどの緯度と中心気圧の関係を示した図に、トップ4までの台風及び[伊勢湾台風](https://www.data.jma.go.jp/obd/stats/data/bosai/report/1959/19590926/19590926.html)、[第二室戸台風](https://www.data.jma.go.jp/obd/stats/data/bosai/report/1961/19610915/19610915.html)の変遷を追記してみました。（トップ4：青、伊勢湾台風：赤、第二室戸台風：黄色。）
```R
tdf2 <- subset(df, df[,1]=="1979T20_TIP")
lines(tdf2$緯度, tdf2$中心気圧, col=4, lwd=4)
tdf2 <- subset(df, df[,1]=="1973T15_NORA")
lines(tdf2$緯度, tdf2$中心気圧, col=4, lwd=4)
tdf2 <- subset(df, df[,1]=="1975T20_JUNE")
lines(tdf2$緯度, tdf2$中心気圧, col=4, lwd=4)
tdf2 <- subset(df, df[,1]=="1958T22_IDA")
lines(tdf2$緯度, tdf2$中心気圧, col=4, lwd=4)

tdf2 <- subset(df, df[,1]=="1959T15_VERA")
lines(tdf2$緯度, tdf2$中心気圧, col=2, lwd=4)
tdf2 <- subset(df, df[,1]=="1961T18_NANCY")
lines(tdf2$緯度, tdf2$中心気圧, col=7, lwd=4)
```

大隅半島以北～東京湾周辺の緯度帯を見ると、これらの観測史上上位の最低気圧を記録した台風に比べて、伊勢湾台風、第二室戸台風の方が、中心気圧が低いことが分かります。当たり前かもしれませんが、**注目する地域において**、台風勢力がどの程度か、という視点を持つことは重要かと思います。

また、中心気圧だけで被害が決まるわけでもないかと考えられます。たとえば、上記で引用した通り、狩野川台風は、日本上陸前に勢力が衰えたようですが、前線が活発化しながら北上したため、東海地方と関東地方では大雨となったようです。

![トップ4経路追加-緯度と中心気圧の関係png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842832/e30f9cd7-f67d-5684-b370-c13279943aab.png)

## レポジトリ
ウェブ地図用のソース、GeoJSON への変換コード、R　スクリプトを置いています。

https://github.com/mghs15/typhoon-besttrack-overview

## 感想

台風位置表とは異なり、独自フォーマットの気象庁ベストトラックでしたが、それでもデータ構造自体は機械判読できるものであり、時間をかけずに処理を行うことができました。このような情報が提供されていることは、ありがたい限りです。

一方、日本語での説明が少ないことや、上陸フラグ等、年次ごとに取得された情報についての説明が少ない点（どこかにあるのかもしれませんが、ダウンロードページ周辺では見つけられず……）が気になりました。いったん記事にはしてみましたが、自分ももう少しリテラシーを高めるべく、色々と周辺情報を調査してみたいと思います。

また、台風の統計がとられているのが、まだ100年経っていないことに少し意外な気持ちになっています。現在、気象庁提供データの台風の識別情報は、西暦の下2桁＋台風番号となっておりますが、100年経つとこれが衝突するので、その際にどうするのか、これも気になるところです。