いつもは、「Automating GIS Processes 2024 写経」を投稿していますが、今回は番外編です。
2025年10月31日から11月3日にかけて、静岡市で大道芸ワールドカップがあります。 Folium によるオンラインマップを学びましたので、パフォーマンス場所(公式ではポイント)のオンランマップを作ってみましょう。
コンセプト
- スマホのブラウザでの使用を想定
- 土地勘のない人でもなんとなくわかるように
- たいていの人が簡単に使えるよう、凝ったことはしない
データ
ファイル名は、Daidougei_world_cup_2025_points.csv
とします。拡張子でわかるように、CSV形式です。
id,name,desc,timeslot,district,lat,lon
1,キリンポイント,駿府城公園の紅葉山庭園前広場の北側。北側の橋から駿府城公園に入ってすぐ。,11:00-19:00,静岡市葵区,34.9800745886027,138.384199519385
2,トコチャン広場,駿府城公園の紅葉山庭園前広場の南側。北側の橋から駿府城公園に入ってすぐ。,11:00-19:00,静岡市葵区,34.9797661965445,138.383920420468
3,SBSどき!どき!ランド,駿府城公園の東御門前広場。南側の橋から駿府城公園に入って、公園内側の通路を反時計回りに。もしくは東側の門から駿府城公園に入って通路を道なりに,11:00-19:00,静岡市葵区,34.9787456196104,138.384186760562
4,アイワポイント,南側の橋から駿府城公園に入って、公園内側の通路を時計回りに。有料のプレミアムシートあり。詳細はhttps://daidogei-gb.com/premium-seat/,11:00-19:00,静岡市葵区,34.979079461549,138.382064572026
5,シズガスポイント,南側の橋から駿府城公園に入ってすぐ。11月1日・2日は11:00-17:30、地元静岡で活動するアーティストやアマチュアがステージに,11:00-19:00,静岡市葵区,34.9778955289323,138.382263928407
6,キッズガーデンポイント,駿府城公園の富士見芝生広場(公園西側)。10月31日は無し,11:00-15:30,静岡市葵区,34.9782993224402,138.381235249466
7,ウォーキングストリート1,南側の橋から駿府城公園に入ってすぐ。アーティストの出演時間帯・場所は非公開。,11:00-19:00,静岡市葵区,34.9781695715767,138.382331681033
8,AFC-HD企業集団プレゼンツプレミアムステージ,静岡市中央体育館。有料。11:00-13:30・17:-00-20:00の2部制。詳細はhttps://daidogei-gb.com/premium-stage/,11:00-20:00,静岡市葵区,34.9816511838764,138.385015861213
9,富士テクノロジーポイント,静岡市中央体育館の前の広場,11:00-19:00,静岡市葵区,34.9815830573316,138.385876850304
10,体感型動物園iZooポイント,静岡市市役所北側入口にある大階段の前。10月31日は無し,11:00-18:00,静岡市葵区,34.9757404302136,138.38276357842
11,福工房札の辻ポイント,呉服町通りと七間町通りの交差点、伊勢丹静岡店前。10月31日は無し,11:00-18:00,静岡市葵区,34.974908997117,138.38178129056
12,ARTIEポイント,七間町通りに面するARTIE(アルティエ)の野外ステージ。詳細はhttps://www.artie-info.com/ ,11:00-18:00,静岡市葵区,34.9742343150152,138.381529743162
13,ウォーキングストリート2,青葉シンボルロードの駐輪場のある区画。アーティストの出演時間帯・場所は非公開。,11:00-18:00,静岡市葵区,34.9737392751387,138.382319878027
14,ウォーキングストリート3,呉服町通りから七間町通り(静岡パルコ前から伊勢丹静岡店前、ARTIE前まで)。アーティストの出演時間帯・場所は非公開。,11:00-18:00,静岡市葵区,34.9738427788549,138.384345921916
15,青葉パークポイント,青葉シンボルロードの両替町通り南側の区画,11:00-18:00,静岡市葵区,34.9734980169363,138.382099289057
16,青葉キリンポイント,青葉シンボルロードの江崎新聞社の近くの区画。11月1日は12:00-18:30,11:00-18:00,静岡市葵区,34.973174325793,138.381943777323
17,ちゅうでん常磐公園ポイント,青葉シンボルロードの終点である常磐公園。他のポイントから離れている。10月31日は無し,11:00-18:00,静岡市葵区,34.9704725323768,138.380228996879
18,しずマチゲートウェイポイント,三菱UFJ銀行静岡支店の前。10月31日は無し,11:00-18:00,静岡市葵区,34.9728756370867,138.387257991352
19,駿河屋ポイント,駿河屋ビル(駿河屋本店)の前。10月31日は無し,11:00-18:00,静岡市葵区,34.9739621182013,138.387548588402
20,駿河屋スゴワザポイント,駿河屋ビル(駿河屋本店)の4階,11:00-18:00,静岡市葵区,34.9741488742277,138.388204965628
21,セノバポイント,新静岡セノバ3階セノバキッチン(フードコート)。フロアマップはhttps://www.cenova.jp/shop/floor.jsp?fid=3f 静岡駅と駿府城公園の中間地点。10月31日は14:00-18:30,11:00-18:00,静岡市葵区,34.975646786955,138.386683719741
22,ドリームプラザ1,エスパルスドリームプラザの海側ウッドデッキ。清水駅・新清水駅からドリームプラザは無料シャトルバスがある。時刻表はhttps://www.dream-plaza.co.jp/shuttle-bus/timetable/ ,11:00-17:00,静岡市清水区,35.010253706182,138.493776551674
23,ドリームプラザ2,エスパルスドリームプラザの海側にあるテルファークレーン(モノレールのようなクレーン)の前。清水駅・新清水駅からドリームプラザは無料シャトルバスがある。時刻表はhttps://www.dream-plaza.co.jp/shuttle-bus/timetable/ ,11:00-17:00,静岡市清水区,35.0109697530046,138.493323315734
内容は、見てもらえばわかるかと。数がそれほど多くないので、コツコツ入力しました。実はdesc列が一番時間かかっています。
dest
の内容の一部は電子版公式ガイドブックのpdfファイル から取得しています。座標(lat
、lon
)はグーグルマップで地図を右クリックすると表示される座標です。
また、最初は静岡市街地と清水区でフィルタリングする構想があったため、district
列があります。が、これは使っていません。
コード
ベースマップにOpenStreetMapを使ったのは、まあ、なんとなくです。
ポイントにより終了時間が異なるので、時間帯ごとに選択できるように、FeatureGroup
でグループ化、LayerControl
でチェックボックスを追加しています。URLは正規表現でハイパーリンクになるように、加工しています。
from folium import FeatureGroup, LayerControl
from folium import Map, Html, Element
import folium
import pandas as pd
import geopandas as gpd
import re
# URLをハイパーリンクに置き換え
def linkify(text):
return re.sub(r'(https?://\S+)', r'<a href="\1" target="_blank" rel="noopener noreferrer">こちら</a>', text)
# 初期表示の座標
center_lat, center_lon = 34.9765, 138.3828
# インタラクティブ地図(ベースマップはOpenStreetMap)を生成
interactive_map = folium.Map(
location=[center_lat, center_lon],
zoom_start=16,
tiles="OpenStreetMap",
attr="OpenStreetMap",
)
# データ読み込み
df = pd.read_csv("Daidougei_world_cup_2025_points.csv")
# GeoDataFrame化
gdf = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df["lon"], df["lat"]), crs="EPSG:4326"
)
# ポップアップHTMLの列を追加
gdf["popupContent"] = gdf.apply(
lambda r: f"<b>{r['id']} {r['name']}</b><br/>{r['timeslot']}<br/><br/>{linkify(r['desc'])}",
axis=1
)
# 時間帯ごとにグループ化し、インタラクティブ地図に追加
for timeslot, subset in gdf.groupby("timeslot"):
fg = FeatureGroup(name=f"{timeslot}")
for _, row in subset.iterrows():
folium.Marker(
location=[row["lat"], row["lon"]],
popup=folium.Popup(row["popupContent"], max_width=300),
tooltip=row["name"],
icon=folium.Icon(color="blue", icon="info-sign"),
).add_to(fg)
fg.add_to(interactive_map)
# 画面の右上に置くレイヤーコントロールを生成し、インタラクティブ地図に追加
LayerControl(collapsed=False, position="topright").add_to(interactive_map)
# 画面の左下に重畳する注釈用HTMLを生成
note_html = """
<div style="
position: fixed;
bottom: 10px;
left: 10px;
width: 300px;
padding: 10px;
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid #ccc;
font-size: 12px;
z-index: 9999;
">
<b>この地図は 個人がまとめたものであり、公式ではありません。</b>
情報は大道芸ワールドカップin静岡2025 公式ガイドブックから抜粋したものです。最新の情報は<a href="https://daidogei.com/guidebook/" target="_blank" rel="noopener noreferrer">オフィシャルサイト</a>をご確認ください。
</div>
"""
# 注釈用HTMLをインタラクティブ地図に追加
interactive_map.get_root().html.add_child(Element(note_html))
# インタラクティブ地図を表示
interactive_map
こうなりました。
まずは、最初に画面を開いたときに表示される、静岡市市街地です。
次に清水区です。こちらは静岡市市街地から離れているので、初期画面では見えない人がほとんどだと思います。
なんらかの対策を打とうかと思いましたが、思っただけでやっていません。
では、作成したオンラインマップをhtmlファイルとして保存します。英語版を作る構想もあるので、ファイル名の末尾は"_jp".htmlとしています。
interactive_map.save("daidougei_world_cup_in_shizuoka_2025_points_jp.html")
余談
今回は公開もしてます。こちらです。
今後の構想(大きいものから小さいものまで)
- 英語版の公開(たぶん別のページで)
- htmlタグ内にtitleタグを追加(現在は手動で追加)
- ウォーキングストリート1・ウォーキングストリート3は広範囲なのでそれがわかるようにしたい
- 清水区のポイントが埋没しているのでどうにかしたい