Combination Streamlit and Folium in VS-code

  I try to create the code using Streamlit and Folium(Steamlit_Folium) and to learn about publicizing the code on the WEB site of the Streamlit.

 I think what kind of Application I will make. I decided to make a code like below.

  • input the latitude and longitude at a point and a radius in our side bar
  • Draw the circle that has an inputed coordinate and the center 

 I ask Gemini like below, in Japanese.

Streamlitを使って、入力した緯度・経度の点とその点を中心とする半径から、Foliumの地図上に当該緯度経度の点をドットで表示したうえで、当該点を中心とする半径の円を描くPythonコードを書いてください。なお、緯度経度と半径の入力はサイドバーを使用したいです。

StreamlitとFoliumを組み合わせることで、サイドバーからインタラクティブに数値を変更し、地図上に反映させるアプリケーションを簡単に作成できます。

以下のコードは、streamlit-folium というライブラリを使用して、Streamlit上にFoliumの地図を表示する実装例です。

実装コード

Python
import streamlit as st
import folium
from streamlit_folium import st_folium

# ページの設定
st.set_page_config(page_title="Map Circle Tool", layout="wide")

st.title("📍 緯度経度を中心とした円の描画")

# --- サイドバーの設定 ---
st.sidebar.header("入力パラメータ")

# 緯度の入力(デフォルト:東京駅)
lat = st.sidebar.number_input(
    "緯度 (Latitude)", 
    min_value=-90.0, max_value=90.0, value=35.6812, format="%.6f"
)

# 経度の入力
lon = st.sidebar.number_input(
    "経度 (Longitude)", 
    min_value=-180.0, max_value=180.0, value=139.7671, format="%.6f"
)

# 半径の入力(メートル単位)
radius = st.sidebar.number_input(
    "半径 (メートル)", 
    min_value=1, max_value=100000, value=1000, step=100
)

# --- 地図の作成 ---
# 地図の初期化(入力された地点を中心に設定)
m = folium.Map(location=[lat, lon], zoom_start=14)

# 中心点にドット(CircleMarker)を配置
folium.CircleMarker(
    location=[lat, lon],
    radius=5,           # ドットの大きさ
    color="red",
    fill=True,
    fill_color="red",
    tooltip="中心点"
).add_to(m)

# 指定された半径の円を配置
folium.Circle(
    location=[lat, lon],
    radius=radius,      # メートル単位
    color="blue",
    fill=True,
    fill_opacity=0.2,
    tooltip=f"半径 {radius}m"
).add_to(m)

# --- Streamlitでの表示 ---
st_folium(m, width=1000, height=600, returned_objects=[])

# 現在の値を表示
st.write(f"現在の設定: 緯度 {lat}, 経度 {lon}, 半径 {radius}m")

実行方法

  1. ライブラリのインストール

    まだインストールしていない場合は、ターミナルで以下を実行してください。

    Bash
    pip install streamlit folium streamlit-folium
    
  2. アプリの起動

    作成したPythonファイルを app.py として保存し、以下を実行します。

    Bash
    streamlit run app.py
    

コードのポイント

  • st.sidebar.number_input: 数値入力欄をサイドバーに配置します。format="%.6f" とすることで、GPS座標のような細かい小数点も扱えるようにしています。

  • folium.CircleMarker: 地図をズームしても大きさが変わらない「ドット」を描画するのに適しています。

  • folium.Circle: 地図上の実際の距離(メートル)に基づいた円を描画します。

  • st_folium: FoliumのオブジェクトをStreamlit上で描画するためのコンポーネントです。

もし、この地図に「CSVファイルを読み込んで複数の点を一括表示したい」といった機能を追加したい場合は、続けてお手伝いしましょうか?

緯度経度と半径の入力は、Streamlitのnumber_input機能を使用したいです。なお、緯度経度の初期値は東京都庁の場所、半径は1kmを初期値にしてください

承知いたしました。東京都庁の座標(緯度: 35.6895, 経度: 139.6917)と半径 1,000m を初期値に設定し、st.sidebar.number_input を活用したコードを作成しました。

実装コード

Python
import streamlit as st
import folium
from streamlit_folium import st_folium

# ページのレイアウト設定
st.set_page_config(page_title="都庁中心の円描画", layout="wide")

st.title("📍 緯度・経度指定による円の描画")

# --- サイドバーの設定 ---
st.sidebar.header("設定パラメータ")

# 1. 緯度の入力(初期値:東京都庁)
lat = st.sidebar.number_input(
    "緯度 (Latitude)", 
    min_value=-90.0, 
    max_value=90.0, 
    value=35.689500, 
    format="%.6f"
)

# 2. 経度の入力(初期値:東京都庁)
lon = st.sidebar.number_input(
    "経度 (Longitude)", 
    min_value=-180.0, 
    max_value=180.0, 
    value=139.691700, 
    format="%.6f"
)

# 3. 半径の入力(初期値:1000m = 1km)
radius = st.sidebar.number_input(
    "半径 (メートル)", 
    min_value=1, 
    max_value=500000, 
    value=1000, 
    step=100
)

# --- Folium地図の作成 ---
# 指定した緯度経度を中心に表示
m = folium.Map(location=[lat, lon], zoom_start=14)

# 中心点のドット(CircleMarker)
folium.CircleMarker(
    location=[lat, lon],
    radius=6,
    color="blue",
    fill=True,
    fill_color="blue",
    tooltip="中心点"
).add_to(m)

# 指定半径の円(Circle)
folium.Circle(
    location=[lat, lon],
    radius=radius,
    color="crimson",
    fill=True,
    fill_opacity=0.2,
    tooltip=f"半径 {radius}m の範囲"
).add_to(m)

# --- 地図の表示 ---
st_folium(m, width=1000, height=600)

# 補足情報の表示
st.info(f"現在、東京都庁(付近)の座標を中心として、半径 {radius / 1000:.1f} km の円を描画しています。")

コードの解説

  • 初期値の設定: number_inputvalue 引数に、ご要望通りの値をセットしています。

    • 緯度: 35.689500

    • 経度: 139.691700

    • 半径: 1000

  • 精度の確保: format="%.6f" を指定することで、緯度経度のような細かい小数点以下(6桁)までサイドバー上で正確に表示・入力できるようにしています。

  • 視認性: CircleMarker(ドット)と Circle(範囲)の色を変えて、中心位置がより分かりやすくなるようにしました。

この地図上に、半径に応じた「周辺の施設情報(コンビニや駅など)」を自動で検索して表示するような機能に興味はありますか?必要であればAPIとの連携方法などもご提案できます。

では、Streamlitで地図を表示して、地図上でクリックした場所の緯度経度を取得することはできますか?

はい、st_folium の戻り値を利用することで可能です。

st_folium 関数は、地図上でのクリックイベントや表示範囲の変更などの情報を Python の辞書(Dict)形式で返してくれます。クリックした場所の座標は、その辞書内の last_clicked というキーに格納されています。

以下に、クリックした場所の座標を取得し、それをサイドバーの入力値に反映(または表示)させる実装例を紹介します。

実装コード

Python
import streamlit as st
import folium
from streamlit_folium import st_folium

st.set_page_config(layout="wide")
st.title("🖱️ 地図クリックで座標を取得")

# セッション状態(クリック座標を保存するため)の初期化
if 'clicked_lat' not in st.session_state:
    st.session_state.clicked_lat = 35.6895
if 'clicked_lon' not in st.session_state:
    st.session_state.clicked_lon = 139.6917

# --- サイドバーの設定 ---
st.sidebar.header("座標と半径の設定")

# サイドバーの入力(セッション状態を初期値に設定)
lat = st.sidebar.number_input("緯度", value=st.session_state.clicked_lat, format="%.6f")
lon = st.sidebar.number_input("経度", value=st.session_state.clicked_lon, format="%.6f")
radius = st.sidebar.number_input("半径 (m)", value=1000, step=100)

# --- 地図の作成 ---
m = folium.Map(location=[lat, lon], zoom_start=14)

# クリック地点にマーカーを表示
folium.Marker([lat, lon], tooltip="選択中の地点").add_to(m)
folium.Circle([lat, lon], radius=radius, color="red", fill=True).add_to(m)

# 地図を描画し、クリックイベントを取得
# returned_objects に "last_clicked" を指定することで情報を取得可能
map_data = st_folium(m, width=800, height=500)

# --- クリック時の処理 ---
if map_data and map_data["last_clicked"]:
    new_lat = map_data["last_clicked"]["lat"]
    new_lon = map_data["last_clicked"]["lng"]
    
    # クリックされた座標が現在のセッションと異なる場合、更新してリラン
    if new_lat != st.session_state.clicked_lat or new_lon != st.session_state.clicked_lon:
        st.session_state.clicked_lat = new_lat
        st.session_state.clicked_lon = new_lon
        st.rerun()

st.write(f"現在の中心座標: {lat}, {lon}")
st.info("地図上をクリックすると、その地点に円が移動します。")

仕組みの解説

  1. map_data["last_clicked"]:

    st_folium を変数(上記では map_data)に代入すると、地図に対する操作ログがリアルタイムで格納されます。クリックすると {'lat': 35.xxx, 'lng': 139.xxx} というデータが取得できます。

  2. st.session_state:

    地図をクリックしてページが再読み込み(リラン)された際、クリックした座標を保持しておくために必要です。これがないと、クリックするたびに初期値(都庁)に戻ってしまいます。

  3. st.rerun():

    新しい座標を取得した瞬間にアプリを強制的に再描画させ、サイドバーの number_input や地図上の円を即座に更新するために使用します。

注意点

クリックしてから地図が更新されるまで、わずかに(コンマ数秒)通信のタイムラグが発生します。これは Streamlit がサーバーサイドで動作しているためです。

この「クリックで取得した座標」を使って、さらに**その場所の住所を自動表示(逆ジオコーディング)**するような機能を追加しましょうか?

 I'd like to signify the center point select on the map, Gemini give the code like above.

 Examplely, the center set Japanese Imperial Palace, the radius set 2_000m, the result is below


  JR Iidabashi St., Yotsuya St., Shinbashi St. Tokyo St. and the others is within this circle.

 Next, I try to publicize this code on the Streamlit. At first, I upload this code to GitHub.

 At first, I log in the GitHub ( I have already registored to GitHub). After I log in the GitHub, I show this one like below.

 For I should create a remort repogitory, I click the '+' button where is upper right side odf Header above windows. Next I input repository name as  'Streamlit_Test_Repository' and since this repository is for practice(test), I select 'Private' as publicity area. 

 Next I open 'Git Bush' like below.

  Next, I try to set up 'Streamlit_Test_Repository' as my current remote repository. I input 'git remote add origin <URL>' , but an error happen like below.

$ git remote add origin

fatal: not a git repository (or any of the parent directories): .git

 Maybe I need to move to the folder that be managed currently, then I input below command on the Git Bush.

$ cd "C:\Users\*****\OneDrive\ドキュメント\VS_Code\2025_StreamlitBasicLearning\2025_StreamlitAndFoliumLearn"

 After I moved to the '2025_StreamlitAndFoliumLearn' folder, I run 'git add .', and  'git commit -m '. After doing it, since I will prepare to upload to GitHub, I check the URL of my repository on my GitHub. The URL is able to be shown in the GitHub's repository page. I confirm that its URL is 'https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git'

 I try to upload( it be called 'Push' on the GitHub') my local repository to GitHub by running the command like below.

'git remote add origin https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git'

  After running above command, I check whether or not be ready to push.

$ git remote -v
origin  https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git (fetch)
origin  https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git (push)

 OK! It's ready to next step. 
 I push my local repository to GitHub's remote repository by running below command.
 
$git push -u origin main
info: please complete authentication in your browser...
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 22 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (10/10), 1.80 KiB | 262.00 KiB/s, done.
Total 10 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

  I ask Gemini whether or not I successed pushing my local repository to GitHub. Gemini recommended me that I should look at my GitHub repository and whether or not there are files and folders of my local repositories.

ブラウザで「Authentication Succeeded(認証成功)」というようなメッセージが表示されましたか? それであれば、認証は完了しています。

次は**ターミナル(MINGW64)の画面**に戻ってください。

### 1. ターミナルの状態を確認する

ターミナルの画面を見て、以下のようなメッセージが出ていれば、**すでにアップロード(Push)は成功しています。**

> `To https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository.git`
> `* [new branch]      main -> main`
> `Branch 'main' set up to track remote branch 'main' from 'origin'.`

このような文字が出ていれば、何もする必要はありません!

### 2. もしターミナルが止まったまま、またはエラーの場合

もしターミナルがまだ「入力を待っている状態」だったり、止まっていたりする場合は、もう一度だけ以下のコマンドを実行してください。

```bash
git push -u origin main

```

※今度はブラウザの認証画面は出ず、すぐにアップロードが始まるはずです。

---

### 3. GitHubで確認する

最後に、実際にアップロードされたか確認しましょう。

1. ブラウザで [GitHubのリポジトリページ](https://www.google.com/search?q=https://github.com/ShikuuKitashirakawa/Streamlit_Test_Repository) を開きます。
2. ページを更新(リロード)してください。
3. あなたのPCにある `2025_StreamlitAndFoliumLearn` フォルダの中身(ファイルなど)が表示されていれば、**すべて完了です!**

無事にファイルは表示されましたか? これで今後、プログラムを書き換えたときは「add → commit → push」の3ステップだけで更新できるようになります。

 Just in case, I describe disclaimer on the GitHub repositorie's Readme Text like below.

日本語

免責事項 本リポジトリのコードおよび情報は、教育的および学習目的でのみ提供されています。本プログラムの使用、適用、または実行によって生じたいかなる損害(データの損失、システムの不具合等)についても、作成者は一切の責任を負いません。すべて利用者の自己責任において使用してください。

英語 (English)

Disclaimer The code and information in this repository are provided for educational and learning purposes only. The author shall not be held liable for any damages (including but not limited to data loss or system failure) arising from the use, application, or execution of this program. Use it at your own risk.

 Before I'll try to use Streamlit Cloud, Gemini is recommended that I should write in Streamlit sidebar like below. 

import streamlit as st
with st.sidebar:
    st.markdown("---")
    st.caption("### Disclaimer / 免責事項")
    st.caption("This app is for educational purposes. Use at your own risk.")
    st.caption("本アプリは学習用です。利用による責任は負いかねます。")

 I added this code to my repository's code, as the result like below.


 I check to push my local repository to GitHub following before I have described.

 Finally, I try to publicize on Streamllit Cloud. At first, I search Streamlit Cloud Home Page on the web site by Google. That is 'https://share.streamlit.io/' whose home page's windown is shown like below.


 I try to sign up and in following their installaction. I registored by my GitHub ID.


 I click 'Create App' at upper right corner of window.


 I selected 'Deploy a public app from GitHub' and write the necessary items like below.(Caution: If you'd like to create Web App from GitHub remote repository by Streamlit, the GitHub remote repository have to set up 'Public'.

 I try to Deploy.

 As the result, I have created Web App on Streamlit.


 I finish this time BLOG.

--ended

コメント

このブログの人気の投稿

Gourmet from June 2025 to September 2025

DINNER, LUNCH AND DRINK from Sept. 2024

Home vegetable gardening from April, 2024