Python Streamlitを使用した基礎的なWebアプリケーションの作成(2) July, 2025

 前回のBlog記事:https://shikuuk.blogspot.com/2025/06/python-folium-relearning8-from-may.html

 DummyDataをMakeUseしたCodeがAlmostCompleteしたので、NextはJapaneseGovのJapanLandNumericalInformation上にある実在のDamInformationをUseして、DamのSpecificationやLocationを表示するAppにevolutionしたいと思います。

 InAdvanceでTryしてみたところ、StreamlitならではのSubjectやproblemが出てきたので、大変勉強になりました。ExamplyにWriteすると、

  • StreamlitでMakeしたAppは、App上で何かOperationするたびに基本的にCodeをInitialOrderからActivateしていくので、今回のようにWeb上のDataBaseを単純にRequest-GetするCodeをWriteすると、OperationのたびにWeb上のDataBaseをRequestしにいくため、Requestが多すぎてErrorになる。

とか、

  • Likely AboveのReasonで、GeoDataFrameのColumnNameをW01_001といったSimbolicSignから「ダム名称」のようなJapaneseにRewriteする際に、RewriteするCodeの位置を間違うと、一度目はうまくRewriteできるけど、App上でOperateがOccureしたあとの2度目の処理の際にHaveRewrittenのColumnNameをSearchしに行き、すでにColumnNameがRewriteされているのでSearchしようとしているColumnNameがFindOutできずにErrorがHappenする

などなどにEncounterしました。StreamlitのHabitをUnderstandしたうえでCodeをWriteするRequirementがExistであることをRealizedでした。

 So, the Conclusion that I come to, at firstで、Web上からGetするInformationを、App内で取り扱いやすいようにInAdvanceにProseccingしておくことだとThinkしました。

 From Here, FirstでJapan Land Numerical InformationのDamInformationをGetして、App内でUseしやすいGeoDataFrameにProseccingします。

 まずは、幹のPartになるFunctionを作成します。


#@st.cache_resource
def func_create_gdf_data():

# 国土数値情報のWebSiteからDataをDownloadする場合
    url = 'http://nlftp.mlit.go.jp/ksj/gml/data/W01/W01-14/W01-14_GML.zip' # 国土数値情報のダムデータを格納しているURLをChoromeのデベロッパーツール活用して確認
    zip_file_path = '/content/W01-14_GML.zip'
    shp_file_name = '/content/unzipped_data/W01-14-g_Dam.shp'
## 一度LocalPCにDownloadしたファイルを使用する場合
#    zip_file_path = 'W01-14_GML.zip' # app.py と同じディレクトリにある場合、ファイル名だけでOK
#    shp_file_name = 'W01-14-g_Dam.shp'

    original_gdf = func_load_map_data(zip_file_path, shp_file_name)

    gdf = func_process_dam_gdf(original_gdf)

    return gdf

# Create the GeoDataFrame
gdf = func_create_gdf_data()

gdf.head(10)

 Firstにある「#@st.cache_resource」が実は肝で、現時点では#を付けて無効化していますが、StreamlitでこのCodeを動かすときにすごくImportantなRoleを果たします。

 まず、MainCodeからfunc_creatr_gdf_data()関数を呼び出して、国土数値情報のURLやZipFileのNameなどを指定し、さらにfunc_load_map_data()関数を呼び出して、そのReturnとなるGeoDataFrameを'original_gdf'として受け取ります。

 func_load_map_data()関数は次のようなContentです。


# --- 国土数値情報のDamInformationをロードする関数 ---
# @st.cache_resource デコレータはそのまま残します。
# これがないと、アプリが再実行されるたびに毎回解凍処理が走ってしまいます。
# (もし実際の国土数値情報データをロードする場合、このデコレータを適用してください)
# @st.cache_resource
def func_load_map_data(zip_file_path, shp_file_name):
    unzipped_dir = 'unzipped_data'

    # 解凍先ディレクトリが存在しない場合は作成
    if not os.path.exists(unzipped_dir):
        os.makedirs(unzipped_dir)

    shp_file_path_in_content = os.path.join(unzipped_dir, shp_file_name)

    # SHPファイルが既に解凍済みで存在するかチェック
    if os.path.exists(shp_file_path_in_content):
        gdf = gpd.read_file(shp_file_path_in_content, encoding='cp932')
        return gdf

    # ZIPファイルを解凍 (withステートメントを削除)
    zip_ref = zipfile.ZipFile(zip_file_path, 'r') # ここでファイルを開く
    zip_ref.extractall(unzipped_dir) # 解凍
    zip_ref.close() # ファイルを閉じるのを忘れないこと!

    # Shapefileを読み込む (try-exceptを削除)
    gdf = gpd.read_file(shp_file_path_in_content, encoding='cp932')
    return gdf












コメント