Pythonでジオコーディング(ChatGPT編)

## はじめに
- 話題のChatGPTですが、画像生成AIのStable Diffusionに続いて、とても話題になっています。私もこちらのエントリーを拝見し、そんなこともできるのか、と驚きました。

https://qiita.com/NasuPanda/items/174f3647a7e862ae3a9f

- コードを提案してくれるのはすごいなぁと思いますが、さらに驚いたのは、会話しながらコードに修正を加えていけるところでした。

- Googleが"これは脅威だ"、と言っていたり、こんな使い方便利！というのも続々でてきています。大手クラウドに組み込まれたり(下記の記事はAzure)、APIの公開で、これまでのチャットボットではない、もう一段レベルがあがったサービスが提供される予感があります。

https://president.jp/articles/-/65432

https://note.com/iritec/n/n496881202f60

https://www.itmedia.co.jp/news/articles/2301/17/news106.html


## コードの自動生成をやってみる

- Qiitaのエントリーをはじめ各所で皆様がすごいとおっしゃっておりますので、私も体感したいということで、プログラムの自動生成についてやってみようと思います。プログラム生成につき、下記の投稿は参考になります(感謝)

https://qiita.com/autotaker1984/items/5b5ac8c01d11fbbbc4a7

- 自分の過去エントリーをChatGPTでやってみたいと思います。

https://qiita.com/yoshi_yast/items/bb75d8fceb712f1f49d1

#### ①プログラムを作りたい、と言ってみます

:::note info
**INPUT:**
pythonを使ってジオコーディングするプログラムを作ってください。

**ChatGPTの返答:**
ジオコーディングには、住所から緯度経度を求める処理と、緯度経度から住所を求める処理があります。どちらの処理を行うプログラムを作成するのでしょうか？
また、ジオコーディングには、オンライン上のAPIを利用する方法と、オフラインのデータベースを使う方法があります。どちらの方法を使うのでしょうか？
ジオコーディングを行うためには、API Keyなどの認証情報や、使用するデータベースのパスなどが必要になる場合がありますので、それらの情報も教えてください。
:::

情報が足りないというありがたいご指摘。

#### ②情報を付加して再度聞いてみます

:::note info
**INPUT:**
pythonを使って、場所名称から緯度経度を求める処理(ジオコーディング)するプログラムを作ってください。
API Keyなどの認証情報は使用しない方法での提案をお願いします。

**ChatGPTの返答:**
場所名称から緯度経度を求めるジオコーディングを行うために、Pythonではgeopyライブラリを使うことができます。geopyライブラリは、複数のジオコーディングサービスを利用することができるので、API Keyなどの認証情報が必要ないオープンソースのサービスも利用することができます。
以下に、場所名称から緯度経度を求めるジオコーディングの例を示します。

```geo1.py
from geopy.geocoders import Nominatim

geolocator = Nominatim(user_agent="geoapiExercises")
location = geolocator.geocode("Tokyo, Japan")
print(location.latitude, location.longitude)
```
このコードでは、Nominatimというジオコーディングサービスを利用して、"Tokyo, Japan"という場所名称から緯度経度を求めています。求められた緯度経度は、location.latitude、location.longitudeで取得することができます。
※注意：geopyはオフラインのデータベースを使っており、多数の問い合わせをすると、IPアドレスがブロックされる可能性があるので注意してください。
:::

注意点まで教えてくれました。
#### ③このまま実行するとライブラリがないと言われますので、そこも聞いてみます

:::note info
**INPUT:**
geopyライブラリのインストール方法を教えてください。

**ChatGPTの返答:**
geopyライブラリを使用するためには、まずPythonのパッケージ管理システムであるpipを使ってインストールする必要があります。
以下のコマンドをターミナルやコマンドプロンプトで実行してください。

```
pip install geopy
```

これでgeopyライブラリがインストールされます。もしくは、以下のコマンドでもインストールができます。

```
python -m pip install geopy
```

インストールが正常に終わったら、Pythonのインタプリタを起動し、以下のようにインポートして、使用することができます。

```
from geopy.geocoders import Nominatim
```

インストールに問題があった場合は、管理者権限で実行するか、もしくはAnacondaなど仮想環境を使ってインストールすることを検討してください。
:::

仮想環境の話までしてくれました。

#### ④今度はAPI KEYを利用した方法も聞いてみます

:::note info
**INPUT:**
pythonを使って、場所名称から緯度経度を求める処理(ジオコーディング)するプログラムを作ってください。
Google API Keyを使用した方法での提案をお願いします。

**ChatGPTの返答:**
Google Maps Geocoding APIを使用して、場所名称から緯度経度を求めるジオコーディングを行うには、Google Maps Platformに登録し、API Keyを取得する必要があります。そして、Pythonのrequestsライブラリを使用して、Google Maps Geocoding APIに対してリクエストを送信します。
以下に、Google Maps Geocoding APIを使用して、場所名称から緯度経度を求めるジオコーディングの例を示します。

```geo2.py
import requests

api_key = "YOUR_API_KEY" # API Keyを設定
location = "Tokyo, Japan" # 場所名称

url = f"https://maps.googleapis.com/maps/api/geocode/json?address={location}&key={api_key}"
response = requests.get(url)
data = response.json()

latitude = data["results"][0]["geometry"]["location"]["lat"]
longitude = data["results"][0]["geometry"]["location"]["lng"]
print(latitude, longitude)
```

このコードでは、requestsライブラリを使用して、Google Maps Geocoding APIに対して、場所名称 "Tokyo, Japan"を渡してリクエストを送信し、その結果から緯度経度を求めています。
注意： Google Maps Platform の使用には利用規約があり、月あたりの使用制限があります。使用量が多い場合は課金される可能性があります。
:::

課金の注意点も流石です。

#### ⑤手元のローカルファイルをアップロードした形にも対応できるか確認してみます

:::note info
**INPUT:**
ローカルPCに、場所名称が複数かかれているTXTファイルがあります。それを取り込んで、pythonを使って、場所名称から緯度経度を求める処理(ジオコーディング)するプログラムを作ってください。出力結果は、CSVにてローカルにダウンロードします。Google API Keyを使用した方法での提案をお願いします。

**ChatGPTの返答:**
TXTファイルから場所名称を読み込んで、Google Maps Geocoding APIを使用して、場所名称から緯度経度を求め、その結果をCSVファイルに書き出すプログラムを以下に示します。

```geo3.py
import requests
import csv

api_key = "YOUR_API_KEY" # API Keyを設定
file_path = "locations.txt" # 場所名称が記載されたTXTファイルのパス
output_file = "geocoding_result.csv" # 出力するCSVファイルのパス

with open(file_path) as f:
    locations = f.readlines()

# CSVファイルに書き出す
with open(output_file, "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Location", "Latitude", "Longitude"])
    for location in locations:
        location = location.strip()
        url = f"https://maps.googleapis.com/maps/api/geocode/json?address={location}&key={api_key}"
        response = requests.get(url)
        data = response.json()

        latitude = data["results"][0]["geometry"]["location"]["lat"]
        longitude = data["results"][0]["geometry"]["location"]["lng"]
        writer.writerow([location, latitude, longitude])
```
このコードでは、TXTファイルから読み込んだ場所名称を順番にGoogle Maps Geocoding APIに対してリクエストを送信し、その結果から緯度経度を求め、csv.writerを使用して、出力先のCSVファイルに書き込んでいます。
:::

ファイルを読み込むときに文字コードに関するエラーになったので、それも聞いてみます。
#### ⑥エラーについて聞いてみる

:::note info
**INPUT:**
pythonでローカルファイルを読み込むときに、以下のようなエラーが発生しました。
UnicodeDecodeError: 'cp932' codec can't decode byte 0x9d in position 14: illegal multibyte sequence

**ChatGPTの返答:**
UnicodeDecodeErrorというエラーは、文字コードの不一致によって発生するエラーです。
このようなエラーが発生する原因は、読み込んだファイルの文字コードと、Pythonの文字コードの設定が異なっているために発生します。
このようなエラーが発生する場合は、open関数の第二引数に文字コードを指定することで解決できます。
例えば、以下のように書き換えることで、読み込むことができます。
```sample.py
with open(file_path, 'r', encoding='utf-8') as f:
    locations = f.readlines()
```
:::


## まとめ
- どの記事にも注意書きがありますが、生成されたコードを鵜呑みにすることは注意が必要ですが、強力なツールであることは間違いないのかなと思います。
- 参考にさせていただいたエントリーにもありましたが、「Pythonで業務を自動化したい」というレベルであれば、ChatGPTのみでいけてしまいます。
- これまでのチャットボットでは、どの分野でも"とりあえず聞いてみるか"、なんて気は一度も起きたことがないのですが、上記のように選択肢のひとつになることがわかりましたし、さらに進化もすると思いますので、積極的に使っていきたいと思います。