GoでGoogle Maps APIを使って場所の詳細情報を取得する（例：東京タワー）

# はじめに
GoでGoogleMapsAPIを使った記事があまりなかったので書いてみました。
GoogleMapsAPIには様々なAPIがあるのですが、今回は[Place](https://cloud.google.com/maps-platform/places?hl=ja)というAPIを使ってみたいと思います！

Placeの詳細情報はこちら。
[Overview | Places API](https://developers.google.com/places/web-service/intro)

# GCPで事前準備
GoogleMapsAPIを使うにはGCPのアカウント作成、プロジェクト作成、APIKEYの取得が必要です。

以下からこれらを作成します。
[Google Cloud Platform](https://cloud.google.com/docs?hl=ja)

詳しい手順はこちらが参考になります。
[Google Maps Platform APIキーの取得・発行について](https://www.zenrin-datacom.net/business/gmapsapi/api_key/index.html)
⇒API有効化では「Place」のAPIを有効化します。

# とりあえず直接たたいてみる
Placeの中にはさらにいくつかの機能があるのですが、まずは基本のsearch機能を使ってみたいと思います。

各リクエストパラメータの詳細はこちらが参考になります。
[Place Search](https://developers.google.com/places/web-service/search)

## 必須パラメータのみ
こんな感じでたたきます！
試しに東京タワーの情報を取得します。

```:request
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?key=(取得したAPIKEY)&input=東京タワー&inputtype=textquery
```

返ってきたjsonがこちら。
必須パラメータだけだと味気ないですね。

```json:response
{
   "candidates" : [
      {
         "place_id" : "ChIJCewJkL2LGGAR3Qmk0vCTGkg"
      }
   ],
   "status" : "OK"
}
```

## リクエストパラメータに`field`を追加する
> Use the fields parameter to specify a comma-separated list of place data types to return. For example: fields=address_component,name,geometry. Use a forward slash when specifying compound values. For example: opening_hours/weekday_text.

詳細な情報を得るには`field`パラメータに色々設定するみたいです。
とりあえず色々追加してみます。

```:request
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?key=(取得したAPIKEY)&input=東京タワー&inputtype=textquery&fields=plus_code,photos,formatted_address,name,geometry
```

返ってきたjsonがこちら。
それっぽいものが返ってきました！

```json:response
{
   "candidates" : [
      {
         "formatted_address" : "日本、〒105-0011 東京都港区芝公園４丁目２−８",
         "geometry" : {
            "location" : {
               "lat" : 35.6585805,
               "lng" : 139.7454329
            },
            "viewport" : {
               "northeast" : {
                  "lat" : 35.66027947989272,
                  "lng" : 139.7469715298927
               },
               "southwest" : {
                  "lat" : 35.65757982010728,
                  "lng" : 139.7442718701072
               }
            }
         },
         "name" : "東京タワー",
         "photos" : [
            {
               "height" : 3024,
               "html_attributions" : [
                  "\u003ca href=\"https://maps.google.com/maps/contrib/115866158754962714954\"\u003eABD RAHMAN DIN\u003c/a\u003e"
               ],
               "photo_reference" : "CmRaAAAA2VO4J5WaFY6Z5-tS2SJKkPhoVCqxjukhhc0b5iadF1EgksxqgJ9PrUipk_6YyHXIbrLhQEsf2cZjJb628Gyj7a61fkFRkjx3HHhmiUs44VRa3DfWT5kghBndXQ4WUL_NEhD2oTfglENvq6tpTpGqvxUvGhTgsdhh44EXIC5MnZKizUygr9LuoA",
               "width" : 4032
            }
         ],
         "plus_code" : {
            "compound_code" : "MP5W+C5 港区、東京都",
            "global_code" : "8Q7XMP5W+C5"
         }
      }
   ],
   "status" : "OK"
}
```

# GoからAPIを実行する
## SDKをインストール

```
$ go get googlemaps.github.io/maps
```

## 実装
[公式github](https://github.com/googlemaps/google-maps-services-go/blob/master/examples/places/textsearch/textsearch.go)を参考に実装します。

```go:main.go
package main

import (
	"context"
	"log"
	"os"

	"github.com/kr/pretty"
	"googlemaps.github.io/maps"
)

func init() {
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env: %s", err)
	}
}

func main() {
	c, err := maps.NewClient("取得したAPIKEY")
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}
	r := &maps.TextSearchRequest{
		Query: "東京タワー",
	}

	res, err := c.TextSearch(context.Background(), r)
	if err != nil {
		log.Fatalf("fatal error: %s", err)
	}

	pretty.Println(res)
}
```

```:実行結果
$ go run main.go 
maps.PlacesSearchResponse{
    Results: {
        {
            FormattedAddress: "4 Chome-2-8 Shibakoen, Minato City, Tokyo 105-0011, Japan",
            Geometry:         maps.AddressGeometry{
                Location:     maps.LatLng{Lat:35.6585805, Lng:139.7454329},
                LocationType: "",
                Bounds:       maps.LatLngBounds{},
                Viewport:     maps.LatLngBounds{
                    NorthEast: maps.LatLng{Lat:35.66027947989272, Lng:139.7469715298927},
                    SouthWest: maps.LatLng{Lat:35.65757982010728, Lng:139.7442718701072},
                },
                Types: nil,
            },
            Name:             "Tokyo Tower",
            Icon:             "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
            PlaceID:          "ChIJCewJkL2LGGAR3Qmk0vCTGkg",
            Scope:            "",
            Rating:           4.400000095367432,
            UserRatingsTotal: 48610,
            Types:            {"tourist_attraction", "premise", "point_of_interest", "establishment"},
            OpeningHours:     &maps.OpeningHours{
                OpenNow:           &bool(true),
                Periods:           nil,
                WeekdayText:       nil,
                PermanentlyClosed: (*bool)(nil),
            },
            Photos: {
                {
                    PhotoReference:   "CmRaAAAAwPa4Fr0AM5xeZcF5ygLaKHUmOeYMqrhlhm1i0fluDX2WQsv7gGbhdIGG4Tj8W8yX6AC35BXtU4RbF7qc5d72CqIo5vXTdub6tXlhEj9r0GjvnsFPpaN0l8GFOLOkI8X8EhBC_84rpT5MTKJ5_UD_ze0wGhRA8g0XTrLRFPBIv6NRjIIHoPQIhA",
                    Height:           3024,
                    Width:            4032,
                    HTMLAttributions: {"<a href=\"https://maps.google.com/maps/contrib/115866158754962714954\">ABD RAHMAN DIN</a>"},
                },
            },
            AltIDs:            nil,
            PriceLevel:        0,
            Vicinity:          "",
            PermanentlyClosed: false,
            BusinessStatus:    "OPERATIONAL",
            ID:                "0f193d8a0df922a2bcb369673944240a8cb182c3",
        },
    },
    HTMLAttributions: {},
    NextPageToken:    "",
}
```

いい感じに取得できました！


# 参考
[Golangで郵便番号から住所を取得するAPIを作成する](https://qiita.com/komatzz/items/822acfb273ccb0db3f48)