今回は、地図作成ライブラリfoliumの大量にあるPluginsの1つ「FeatureGroup」と、層を分けて表示できるようにする「LayerControl」の使い方。
FeatureGroupのfeature
は特徴という意味で、地図を特徴ごとに層で別けて地図に追加します。
LayerControlは、ラジオボタン・チェックボタンで層の表示を選択でできるようにする優れものです。
特徴が分かりやすいように、電車の路線図ごとに層を分けて作ってみます。
【実行環境】
座標の準備
適当に座標を用意します。FeatureGroupで地図の層を分けますので、グループ分けしやすい感じのが面白いかと思います。縄文遺跡と弥生遺跡の座標とか。
今回はJR長崎本線と、JR大村線、島原鉄道の各駅の座標ごとを3層に分けて地図を作ります。
座標のデータはgeocoding.jp
で集めていた自家製ファイルを使います。
そのファイルを読み込みます。座標のデータを整えてるだけなのでこの部分は無視でいいです。
import pandas as pd # 座標を溜め込んだ自作のファイル fname = 'latlng_list.csv'# CSVを読み込み df = pd.read_csv(fname, header=None) # 条件抽出 df = df[df[0].str.contains("長崎本線|大村線|島原鉄道")] # カラム名の変更 df = df.rename(columns={0:"駅名", 1:"緯度", 2:"経度"}) # 表示 df
駅名 | 緯度 | 経度 | |
---|---|---|---|
141 | JR長崎本線新鳥栖駅 | 33.370455 | 130.491052 |
142 | JR長崎本線肥前麓駅 | 33.365995 | 130.478120 |
143 | JR長崎本線吉野ヶ里公園駅 | 33.324845 | 130.399378 |
144 | JR長崎本線神埼駅 | 33.315766 | 130.374474 |
145 | JR長崎本線伊賀屋駅 | 33.290268 | 130.336784 |
... | ... | ... | ... |
226 | 島原鉄道三会駅 | 32.814989 | 130.357183 |
227 | 島原鉄道島原駅 | 32.790225 | 130.370594 |
228 | 島原鉄道霊丘公園体育館駅 | 32.782476 | 130.374161 |
229 | 島原鉄道島原船津駅 | 32.775957 | 130.375543 |
230 | 島原鉄道島原港駅 | 32.768873 | 130.370548 |
77 rows × 3 columns
地図の中心座標を算出する
上のデータフレームから列で平均値を算出し、中心座標とします。
# 中心座標を平均値で求める center = df.mean(axis=0).tolist() center
[33.01485233766233, 130.22280514285708]
各層に設置するマーカーの座標を準備する
路線ごとに色分けしたマーカーを駅の座標に差します。条件抽出で路線ごとの座標を抽出します。
# 長崎本線の駅の座標を抽出 Nagasaki_data = df[df["駅名"].str.contains("長崎本線")] # 2行のみ表示 Nagasaki_data.head(2)
# JR大村線の座標データを抽出 Oomura_data = df[df['駅名'].str.contains("大村線")] # 島原鉄道の座標データを抽出 Shimabara_data = df[df['駅名'].str.contains("島原鉄道")]
座標の準備ができました。
地図を描く
- ベースとなる地図を作成
- 各層を作成
- 各層にマーカーを追加
- ベース地図に各層を追加
の手順で作成します。
ベースの地図作成
import folium from folium import FeatureGroup, LayerControl # ベースとなる地図を作成 m = folium.Map( location = center, # 中心座標 zoom_start=9 )
各層を作成
# 長崎本線の層を作成 Nagasaki_group = FeatureGroup(name="JR長崎本線") # 長崎本線グループにマーカーを差す ng_popups = Nagasaki_data["駅名"].values.tolist() # popup用の駅名配列 ng_latlngs = Nagasaki_data.iloc[:,1:3].values.tolist() # 座標の2次元配列# 赤のマーカーを各駅の座標に差し、グループに追加for name, latlng inzip(ng_popups, ng_latlngs): folium.Marker( location=latlng, popup=name, icon = folium.Icon(color="red") ).add_to(Nagasaki_group) # 大村線も以下同様 Oomura_group = FeatureGroup(name="JR大村線") Oo_popups = Oomura_data["駅名"].values.tolist() Oo_latlngs = Oomura_data.iloc[:,1:3].values.tolist() for name, latlng inzip(Oo_popups, Oo_latlngs): folium.Marker( location=latlng, popup=name, icon = folium.Icon(color="green") ).add_to(Oomura_group)
# 島原鉄道も同様 Shimabara_group = FeatureGroup(name="島原鉄道") sb_popups = Shimabara_data["駅名"].values sb_latlngs = Shimabara_data.iloc[:,1:3].values.tolist() for name, latlng inzip(sb_popups, sb_latlngs): folium.Marker( location=latlng, popup=name, icon=folium.Icon(color="purple") ).add_to(Shimabara_group)
ベースの地図に層を追加
# 1層だけ地図に追加 Nagasaki_group.add_to(m) # 表示 m
<folium.map.FeatureGroup at 0x7fd4fa598b20>
他の層も地図に追加させてみる。
# 残り2層も地図に追加 Oomura_group.add_to(m) Shimabara_group.add_to(m) # 表示 m
<folium.map.FeatureGroup at 0x7fd4fa5984c0>
これは3層が重なった状態。
路線図であることとマーカーを色分けしているので違いが分かりますが、そうでない場合は混ざって表示されますので見にくいかと思います。
そこで登場するのが次です。
LayerControlで層を分離
地図に層を追加させたたけだと上のように全部一緒くたに表示してしまいますので、LayerControl
を使うことによって層を任意に分離できるようにします。
# 層をラジオボタンで表示選択可能に LayerControl().add_to(m) # 表示 m
層ごとにチェックボタンで表示の切り替えができる。
ナイスです (*´・ω・`)b!
参考リンク
- folium公式
plugins — Folium 0.12.1 documentation
おわりに
地図をブログにすべて貼り付けたら投稿文字数が40万字近くなり、下書き時点でプレビューの表示がバグったので、地図の代わりに画像を貼り付けました。座標が多すぎた。
層ごとにグループ分けができるので、いろんな使い途がありそうですね。
以上です。