見出し画像

shpファイルとkmlファイルを作る

明日1限マップ公開する予定だけど、その前にもうこの記事出すことにした。まあ問題ないでしょうから


 時刻表を基に1限マップ用のデータを作るという作業をようやく終えた。今度はいよいよ、そのデータをGISに載せる。しかし、データをそのまま利用することはできない。
 CSVでもExcelファイルでもいけない。GIS用に、shpファイルを作る必要がある。これ以外にもGIS向けのファイル形式はあるが、前回にならってshpファイルを採用した。ちなみに、shpファイルを作るためのコードは、去年日吉版を作るにあたり、ChatGPTに作成してもらった。今回も、そのコードを再利用し、一部は今回のために変更を加えた。

 細かい説明はともかく、とにかく作業の部分だけを記しておく。相も変わらず雑な備忘録である。

Excel上で評価を並べ替える

 今回はkmlファイルも併せて作成する。これはGoogle Mapでの表示も可能にするためだ。Map上のプロットについて、アイコンを変更できるので、従来の凡例に基づきランク(ABC)ごとに色を変えたい。

 まずはこんな感じで、データを全てgrade(E列)のアルファベット順に並べ替えた。ちなみにgrade以外の情報は「駅データ.jp」より取得している。これも去年と同じだ。
 Q列にあるのは、Pythonでデータを定義づけるために作成した。例えばセルQ2には

="['"&C2&"', '"&D2&"', '"&E2&"', "&F2&", "&J2&", "&K2&"], "

と入力している。なお、セルQ1もコード上で必要になるのだが、

="['"&C1&"', '"&D1&"', '"&E1&"', '"&F1&"', '"&J1&"', '"&K1&"'], "

となっていることに注意してほしい。下図はQ1,2を拡大したものだが、Q2は駅名と時刻とgradeだけクオーテーションが付いている。対してQ1は全ての文字列をクオーテーションで囲う必要がある。


 現時点でかなり読みにくい文章で、大変申し訳ない。備忘録でしかないので、もし不明な点があれば気兼ねなく問い合わせてください。

Pythonを利用する

 さて、今後用いるのはP,Q列だ。A~Iまで評価があるが、Fまではさっき執筆前に終えたので、Gの作業を進める。Pythonには予めgeopandasとsimplekmlをインストールしてください。
 ベースとなるコードは以下の通り。

#三田キャン1限マップ用shpファイル作成Pythonコード
import geopandas as gpd

#データのリストを作成
data = [

ここにデータをペーストする

]

#geopandasのDataFrameを作成
df = gpd.GeoDataFrame(data, columns=['station_name', 'time', 'grade', 'line_cd', 'lon', 'lat'], 
                      geometry=gpd.points_from_xy([record[4] for record in data], [record[5] for record in data]))

#座標系情報の設定
df.crs = "EPSG:4326"

#保存先のディレクトリパスを指定
save_dir = r"(任意のパス)"

#shpファイルとして保存
df.to_file(save_dir + '/任意のファイル名.shp')

#import simplekml

#simplekmlのインスタンスを作成
kml = simplekml.Kml()

#GeoDataFrameから各行をループしてポイントを追加
for index, row in df.iterrows():
    # addpointメソッドを使って、緯度経度、名前、説明等を設定
    pnt = kml.newpoint(name=row['station_name'], coords=[(row['lon'], row['lat'])])
    pnt.description = f"Time: {row['time']}, Grade: {row['grade']}, Line Code: {row['line_cd']}"

#KMLファイルを保存
kml.save(f"{save_dir}/任意のファイル名.kml")

 コード内の「ここにデータをペーストする」と「任意のファイル名」は適宜変更していただきたい。
 このコードのほぼすべてはChatGPT 3.5が作成したものだ。コマンドプロンプト上でエラーが発生すればいちいちChatGPTに相談した。その何回にも渡る修正と実行によって完成した。無料版でもそれなりにコーディングできるので、金銭の生じないようなプログラミングにはとても有効だと思う。

上図のように、評価GのP,Q列をコピーする。私は、先のPythonコードをメモ帳に貼り付け、「ここにデータをペーストする」の部分にP,Q列を貼り付けた。

#三田キャン1限マップ用shpファイル作成Pythonコード
import geopandas as gpd

#データのリストを作成
data = [
	['熱海', '646', 'G', 11504, 139.077679, 35.103573], 
	['来宮', '643', 'G', 11504, 139.065575, 35.098723], 
	['伊豆多賀', '638', 'G', 11504, 139.066847, 35.059411], 
(中略)
	['塔ノ沢', '645', 'G', 99339, 139.094016, 35.234521], 
	['大平台', '635', 'G', 99339, 139.073849, 35.238664], 
	['下館', '631', 'G', 99330, 139.978582, 36.304275], 
]

#geopandasのDataFrameを作成
df = gpd.GeoDataFrame(data, columns=['station_name', 'time', 'grade', 'line_cd', 'lon', 'lat'], 
                      geometry=gpd.points_from_xy([record[4] for record in data], [record[5] for record in data]))

#座標系情報の設定
df.crs = "EPSG:4326"

#保存先のディレクトリパスを指定
save_dir = r"(任意のパス)"

#shpファイルとして保存
df.to_file(save_dir + '/MitaFirstG.shp')

import simplekml

#simplekmlのインスタンスを作成
kml = simplekml.Kml()

#GeoDataFrameから各行をループしてポイントを追加
for index, row in df.iterrows():
    # addpointメソッドを使って、緯度経度、名前、説明等を設定
    pnt = kml.newpoint(name=row['station_name'], coords=[(row['lon'], row['lat'])])
    pnt.description = f"Time: {row['time']}, Grade: {row['grade']}, Line Code: {row['line_cd']}"

#KMLファイルを保存
kml.save(f"{save_dir}/MitaFirstG.kml")

 上記コードでは「ここにデータをペースト」の箇所にP,Q列が貼り付けられているのが分かる。空白のP列を併せて貼り付けることで、tab一つ分のインデントが作られるので、この状態でコピペするのがよい。
 また今回、ファイル名はMitaFirstGとなっているが、これをグレード別に変えていく。

 細かい話になるが、kmlをGoogle my mapでインポートすると、レイヤーごとに一括でアイコンを変えることが出来る。つまり評価別にkmlファイルを作成することで、あとあとGoogle My Mapで設定させるのが楽になるのだ。小難しい話になったが、分からなければ全く構わない。

 ついでにまた細かい話をするが、今回は駅名('station_name')と出発時刻('time')とその評価('grade')、路線コード('line_cd')、経度('lon')、緯度('lat')のみ抽出した。もしこれ以外の要素を加える場合には、コード内「record[4]」と「record[5] 」の箇所の変更も忘れないように。インデックス番号の説明は面倒だから割愛。

さあ、やっと、実行しよう。
prj, shp, shx, cpg, dbfの5つのファイル(GISソフト用)とkmlファイル(Google map用)の延べ6つのファイルを得られたと思う。

深夜2時に作業していることがバレてしまう。

ということで、まだ作業があるのでこれにて。もし説明不十分だと思い立った時にはまた備忘録を残そうと思う。

この記事が気に入ったらサポートをしてみませんか?