■作成プログラムの概要
・場所の名前と住所を記入しているcsvファイルをインプットに、緯度経度を取得し、結果をExcelファイルに出力する。
■フローチャート
▼メイン処理
▼住所情報読み込み処理
▼緯度経度変換処理
▼Excelファイル出力処理
■プログラム仕様
▼メイン処理
処理名 | メイン処理 |
---|---|
処理概要 | 本プログラムの主処理。 住所情報(csvファイル)を読み込み、緯度経度を取得し、Excelファイルに出力する。 |
引数 | なし |
戻り値 | なし |
入力 | 処理内容 | 出力 |
---|---|---|
【csvファイル】 住所情報 | 住所情報読み込み処理を実行する。 | – |
– | 緯度経度変換処理を実行する。 | 【コンソール】 住所情報なし |
– | Excelファイル出力処理を実行する。 | 【Excel】 緯度経度付与済み 住所情報 |
▼住所情報読み込み処理
処理名 | 住所情報読み込み処理 |
---|---|
処理概要 | 住所情報を記載している、csvファイルを読み込む。 |
引数 | なし |
戻り値 | 住所情報 |
入力 | 処理内容 | 出力 |
---|---|---|
【csvファイル】 住所情報 | 住所情報読み込む。 input_address.csv | – |
– | 戻り値として住所情報を返す。 | – |
▼緯度経度変換処理
処理名 | 緯度経度変換処理 |
---|---|
処理概要 | csvファイルから読み込んだ住所情報から、 APIを使用して、緯度経度を取得する。 なお、取得できなかった場合は「-」とする。 (※)使用するAPI http://www.geocoding.jp/api/ |
引数 | 住所情報 |
戻り値 | 住所情報(緯度経度付与済み) |
入力 | 処理内容 | 出力 |
---|---|---|
– | 住所情報のデータに緯度経度の列を追加する。 | – |
– | ループカウンタの初期値(i = 0)をセットする。 | – |
– | ■ループ処理:住所情報のデータ件数分繰り返す。 |・緯度経度の初期値「-」をセットする。 |・APIの所定のフォーマットに住所データをセットし、 | 緯度経度を取得する。 |▼条件分岐 ||【緯度経度取得結果がエラーの場合】 ||・エラーを出力する。 |----- ||【緯度経度取得結果がエラーではない場合】 ||・緯度経度を変数にセットする。 |▲ |・緯度経度を住所情報に追加する。 ■ | 【コンソール】 [error]緯度経度が見つかりませんでした:<住所> |
– | 戻り値として、緯度経度追加済みの住所情報を返す。 | – |
▼Excelファイル処理
処理名 | Excelファイル出力処理 |
---|---|
処理概要 | csvファイルの住所情報と緯度経度をExcelファイルに出力する。 |
引数 | 住所情報+緯度経度 |
戻り値 | なし |
入力 | 処理内容 | 出力 |
---|---|---|
– | Excelファイルを作成し、開く。 | 【Excelファイル】 緯度経度 |
– | 先頭のシートを選択 | – |
– | 表のヘッダー:セルに値を入力する。 | 【Excel セル値】 B2:No. C2:場所 D2:住所 E2:緯度 F2:経度 |
– | 塗り潰しを黄色に設定 | – |
– | ■ループ処理:行数分ループ(1〜2行目まで) |■ループ処理:セル分ループ(A1、・・・、F2) ||▼条件分岐 |||【セルに値が入力されている場合】 |||・黄色に塗り潰し ||▲ |■ ■ | 【Excel セル】 黄色 |
– | 「No.」、「出力開始行」、「ループカウンタ」を初期化 No.=1 出力開始行=3(行目) ループカウンタ=0 | – |
– | ■ループ処理:住所情報のデータ件数分繰り返す |・「No.」を出力する(B列)。 |・「場所」を出力する(C列)。 |・「住所」を出力する(D列)。 |・「緯度」を出力する(E列)。 |・「経度」を出力する(F列)。 |・「No.」、「出力開始行」、「ループカウンタ」を | インクリメント ■ | 【Excel セル値】 Bi:No. Ci:場所 Di:住所 Ei:緯度 Fi:経度 i:任意の行数 |
– | ■ループ処理:Excelの列数分ループ(A〜F列) |・列幅の最大値を初期化(=0) |・列番号を取得(A〜F) |■ループ処理:セル分ループ(A1、・・・、Fi) ||▼条件分岐 |||【セル値の文字数>列幅の最大値】 |||・列幅の最大値=セル値の文字数 ||▲ |■ |・列幅の最大値にバッファを設定(+2文字×1.75) |・列幅を補正する。 ■ i:任意の行数 | – |
– | 罫線の種類を設定する(実線、黒色) | – |
– | セルの罫線を設定する部分をセットする。 (セルの上下左右を対象とする) | – |
– | ■ループ処理:Excelの行数分ループ(1行目〜i行目) |■ループ処理:セル分ループ(A1〜Fi) ||▼条件分岐 |||【セルに値が設定されている場合】 |||・罫線を設定する。 ||▲ |■ ■ i:任意の行数 | – |
– | Excelファイルを保存する。 (保存名:output_address.xlsx) | – |
– | Excelファイルを閉じる。 | – |
■csvファイルレイアウト
・input_address.csv
場所の名前と住所をカンマ「,」区切りで設定する。
※ソースファイルと同階層のフォルダに格納する。
name, address
札幌駅,北海道札幌市北区北6条西4丁目
東京駅,東京都千代田区丸の内1-9-1
新大阪駅,大阪府大阪市淀川区西中島5-16-1
博多駅,福岡県福岡市博多区博多駅中央街1−1
住所ではないデータ,hogehogehogehoge
■Excelファイルレイアウト
・output_address.xlsx
「No.」、「場所の名前」、「住所」、「緯度」、「経度」を表形式で出力する。
なお、存在しない住所の場合、「緯度」、「経度」はハイフン「-」とする。
※ソースファイルと同階層のフォルダに出力する。
■サンプルコード
import requests
from bs4 import BeautifulSoup
import openpyxl
from openpyxl.styles import PatternFill
from openpyxl.styles.borders import Border
from openpyxl.styles.borders import Side
import pandas as pd
# 定数
URL = 'http://www.geocoding.jp/api/' # 住所を緯度経度に変換するAPI
INPUT_CSVFILE = 'input_address.csv' # インプットの住所情報ファイル名
OUTPUT_EXCELFILE = 'output_address.xlsx' # インプットの住所情報ファイル名
def input_address_csv():
'''
処理名
住所情報(csvファイル)読み込み処理
処理概要
住所情報を記載している、csvファイルを読み込む
引数
なし
戻り値
住所情報
'''
df_address = pd.read_csv(INPUT_CSVFILE, index_col=None)
return df_address
def change_latlons(df_csv_data):
'''
処理名
緯度経度変換処理
処理概要
csvファイルから読み込んだ住所情報から、
APIを使用して、緯度経度を取得する。
なお、取得できなかった場合は「-」とする。
引数
住所情報
戻り値
住所情報+緯度経度のデータ
'''
# 住所情報のデータに緯度経度の列を追加
df_csv_data = df_csv_data.assign(lat='-')
df_csv_data = df_csv_data.assign(lon='-')
# 初期値をセット
i = 0
# csvファイルのデータ件数分ループ処理
for i in range(len(df_csv_data)):
# 初期値をセット
tmp_address = ''
tmp_lat = '-'
tmp_lon = '-'
# APIの所定のフォーマットに住所データをセットし、緯度経度を取得する
tmp_address = df_csv_data.iloc[i][1]
payload = {"v": 1.1, 'q': tmp_address}
req = requests.get(URL, params=payload)
result = BeautifulSoup(req.content, 'xml')
# 緯度経度取得結果を確認する
if result.find('error'):
print("[error]緯度経度が見つかりませんでした:", tmp_address)
else:
# 緯度経度を変数にセット
tmp_lat = result.find('lat').string
tmp_lon = result.find('lng').string
# 緯度経度を住所情報データに追加する
df_csv_data['lat'][i] = tmp_lat
df_csv_data['lon'][i] = tmp_lon
return df_csv_data
def output_excel(address_data):
'''
処理名
Excelファイル出力処理
処理概要
csvファイルの住所情報と緯度経度をExcelファイルに出力する
引数
住所情報+緯度経度
戻り値
なし
'''
# Excelファイルを作成
wb = openpyxl.Workbook()
# 先頭のシートを取得(注意:インデックス番号は0から始まる)
ws = wb.worksheets[0]
# 表のヘッダー:セルに値を入力
ws['B2'] = 'No.'
ws['C2'] = '場所'
ws['D2'] = '住所'
ws['E2'] = '緯度'
ws['F2'] = '経度'
# 表のヘッダー:黄色を変更
fill = PatternFill(patternType='solid', fgColor='ffff00')
# 行数分ループ(A1〜F1、A2〜F2)
for row in ws:
# セル分ループ(A1、・・・、F1、A2、・・・、F2)
for cell in row:
# 値が入力されている場合
if ws[cell.coordinate].value:
# 塗り潰し
ws[cell.coordinate].fill = fill
# 「No.」、「出力開始行(3行目から出力)」、「カウンタ」の初期値をセット
i_No = 1
i_row = 3
i = 0
# 住所情報の件数分ループ処理
for i in range(len(address_data)):
# Noを出力
ws.cell(i_row, 2).value = i_No
# 場所を出力
ws.cell(i_row, 3).value = address_data.iloc[i][0]
# 住所を出力
ws.cell(i_row, 4).value = address_data.iloc[i][1]
# 緯度を出力
ws.cell(i_row, 5).value = address_data.iloc[i][2]
# 経度を出力
ws.cell(i_row, 6).value = address_data.iloc[i][3]
# インクリメント
i_No = i_No + 1
i_row = i_row + 1
i = i + 1
# Excelの列分ループ
for col in ws.columns:
# 列幅の最長を初期化
max_length = 0
# 列番号を取得(A、B、C、・・・、F)
column = col[0].column_letter
# セル分ループ(A1、・・・、Ai、・・・、F1、・・・、Fi)
for cell in col:
# セル値の文字数より列幅の最長が大きい場合
if len(str(cell.value)) > max_length:
# 列幅の最長をセル値の文字数に変更
max_length = len(str(cell.value))
# 列幅の最長にバッファを追加(2文字分追加)*1.75
adjusted_width = (max_length + 2) * 1.75
# 列幅を補正
ws.column_dimensions[column].width = adjusted_width
# 罫線の種類を設定する
side = Side(style='thin', color='000000')
# セルの罫線を設定する部分をセット
border = Border(top=side, bottom=side, left=side, right=side)
# Excelの行数分ループ(A1〜F1、・・・、Ai〜Fi)
for row in ws:
# セル分ループ(A1、・・・、Ai、・・・、F1、・・・、Fi)
for cell in row:
# セル値が入力されている場合
if ws[cell.coordinate].value:
# 罫線を設定する
ws[cell.coordinate].border = border
# Excelファイルを保存
wb.save(OUTPUT_EXCELFILE)
# Excelファイルを閉じる
wb.close()
def main():
'''
処理名
メイン処理
引数
なし
戻り値
なし
'''
# 住所情報(csvファイル)読み込み
df_input_address = input_address_csv()
# 住所情報を緯度経度に変換する
df_input_address_latlon = change_latlons(df_input_address)
# エクセルに住所と緯度経度を出力する
output_excel(df_input_address_latlon)
# メイン処理実行
if __name__ == '__main__':
main()
■実行結果
・コンソールの出力結果
[error]緯度経度が見つかりませんでした: hogehogehogehoge
・Excelファイルの出力結果