GoogleMapAPIの実装手順

こんにちは、たにーです。

今回は、地図機能の実装です。
GoogleMapでAPIを取得する手順から実装まで纏めます。

実際に動かしながらやりました。
意外とうまく行かず苦戦しましたが、参考まで。

#前提

- Googleアカウントが既にある
- 開発しているアプリがある。ない場合は、作成してください。（rails new 〇〇）
- ruby 2.6.3
- Rails 5.2.4.5

#Google Maps Platformに登録
下記にアクセスし、始めるをクリックしましょう。
https://cloud.google.com/maps-platform

|![スクリーンショット 2021-03-30 15.45.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/4f33df21-e525-c7ba-ad7f-52c245993d2d.png)
|:


国を選択し、利用規約に✅ を入れます。メールの更新は任意で構いません。

|![スクリーンショット 2021-03-30 15.55.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/3926614a-a12f-ff6d-c6be-81f490ccc5c8.png)
|:

次にアカウントタイプと支払い情報の入力です。

詐欺防止のため、クレジットカードの登録が必須です。
ただ、書いてある通り、無料トライアルが終わったら、こちら側で設定しない限り請求が発生しない仕組みになっています。

account type   => 個人(individual)か、ビジネス(Business)を選択。
payment method => クレジットカード（デビットカード）か、Paypalを選択。

入力し終えたら、無料トライアルを開始するをクリック。

|![スクリーンショット 2021-03-30 16.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/d83ec404-1992-3e01-198f-5ae46977eb3f.png)
|:

次に、プロダクトを選択しましょう。

下記の画面で、プロダクト選択するように指示があるので、
全てに✅ を入れましょう。

その後、有効にするをクリック。

|![スクリーンショット 2021-03-30 16.14.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/cd6a93c3-84ab-3985-a5c8-c9713b56629d.png)
|:

そうすると、下記の画面が表示されます。
問題なければ、完了をクリック。

|![スクリーンショット 2021-03-30 16.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/ee3b16f5-6110-1d9f-88fd-d408d407982a.png)
|:

登録は以上です。

#Google Could Platformでの設定

ヘッダーにある[My First Project]をクリックすると、
プロジェクトの選択画面が表示されます。

右上にある新しいプロジェクトをクリックして、新規で作成しましょう。

|![スクリーンショット 2021-03-30 16.19.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/ab1232a6-2570-c828-8de4-f81e9f59aaab.png)
|:


##まずは、プロジェクトを作成

クリックした後は、プロジェクト名を入力し作成してください。
作成後は、ヘッダーにある[My First Project]をクリックしたら先ほど作成したプロジェクトがあります。
クリックして移動。

そうすると、下記画面が表示されます。

|![スクリーンショット 2021-03-30 16.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/355c8f32-0f42-7b1d-24d2-4d53f05bb7fd.png)
|:

##Maps JavaScript APIを有効化

検索でも画面で探すかで、**「Maps JavaScript API」**を選択する。

|![スクリーンショット 2021-03-30 16.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/355c8f32-0f42-7b1d-24d2-4d53f05bb7fd.png)
|:

画面遷移され、ダッシュボードに飛びます。
その後、左側列にある認証情報をクリック。

この時点では、APIはまだありません。
認証情報を作成しなくてはいけません。不正利用を防ぐためです。

認証情報画面の上段にある**「＋ 認証情報を作成」**をクリック。

|![スクリーンショット 2021-03-30 16.35.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/8e61e9b2-e04c-53ff-fe29-bb4facdc2c07.png)
|:

入力項目は2箇所です。

- アプリケーションの制限（HTTPリファラー（ウェブサイト））
- ウェブサイトの制限(下記の4を入力)

|No.| リファラー | 意味 |
|:-:|:-:|:-|
|1| http://*.example.com/*   | www等のサブドメインがついた example.com　と下位のURL |
|2| https://example.com/*| example.com　と下位のURL  |
|3| localhost/* | ローカルのテスト環境で使う場合。  |
|4| *amazonaws.com/* | cloud9下で行う場合、これで通りました。  |

もし、URLが異なるようでしたら自分で確認する画面のURlを入ればいいかと思います。
  
|![スクリーンショット 2021-03-30 22.45.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/60107d78-edb7-f23e-762b-d4d3ffc89f38.png)
|:

入力できたら、保存をクリック。
無事、APIが発行されました。

|![スクリーンショット 2021-03-30 16.50.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/4f0c4ae8-77a1-1322-611a-d4f87ca382d1.png)
|:

#Google Map APIを実装してみよう

チュートリアルがあるので、これを参考にやっていきます。

https://developers.google.com/maps/documentation/javascript/overview?hl=ja#maps_map_simple-html

自分が練習で作成していたご飯投稿アプリで、
お店の名前をクリックした際に、遷移先で自動的にそのお店を検索し、
地図で位置を表したいと思います。


##コントローラーとビュー作成
まずは、自分のアプリ移動し、コントローラーとビューを作成しましょう。

```terminal:terminal
 $ cd 〇〇                          #自分のアプリに移動。
 $ rails g controller maps index   #マップ用のコントローラーとページを作成
```

ルーティングも設定。
一番下に追記しました。

```rb:routes.rb
Rails.application.routes.draw do
  rroot to: "homes#top"
  resources :foods, only:[:index, :show, :edit, :update, :create, :destroy] do
    resources :food_comments, only:[:create, :destroy]
    resource :likes, only: [:create, :destroy]
  end
  resources :users, only:[:index, :show, :edit, :update]

  resources :users, only:[:index]   #追記
```

maps/indexページを記述。
YOUR_API_KEYに先程のAPIキーを入力しましょう.

```erb:app/views/maps/index.erb
<div id='map'></div>

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>
<!--Google Map APIの指定URLを記述。-->
```

<details><summary>scriptタブ</summary><div>
< scriptスクリプト 属性="属性値">~< /script >
<br>
**script要素**
 クライアントサイドスクリプトのコードを埋め込んで実行します。外部ファイルとして用意したJavaScriptをsrc属性で読み込んで実行できるほか、script要素内に直接ソースコードを記述することもできます。
<br>
**srcソース**
文書内にJavaScriptの外部リソースのURLを指定します。
</div></details>
----
CSS設定
サイズ感は、お好みで設定してください。

```rb:app/assets/stylesheets/maps.scss
#map {
  width: 100%; 
  height: 500px;
}
```

次は、jsファイルを記述します。

```js/app/assets/javascripts/application.js
let mapInstance;   //変数を宣言

function initMap() {  //initMapという関数を定義
  mapInstance = new google.maps.Map(document.getElementById("map"), {   //getElementByIdで指定したIDとマッチするドキュメンを取得するメソッド。
    center: { lat: -34.397, lng: 150.644 },  //地図の中央位置を指定。位置座標を表すパラメーター(lat:緯度、lng:経度)
    zoom: 8, //15がおすすめかもしれない  ///数字で地図の拡大範囲を表す
  });
}
```

centerで記述してある緯度経度は、Webで簡単に調べれます。
例として、東京駅なら、center: { lat: 35.681236, lng: 139.767125 },です。

<details><summary>zoomに関して</summary><div>

| Zoom No. | 拡大範囲 |
|:-:|:-:|
| 1  |  世界 |
| 5 |  陸地/大陸 |
| 10 | 市  |
|  15| 通り  |
|  20| 建物  |
※GoogleMapAPIドキュメント引用


</div></details>
----

現状確認してみましょう。

|![スクリーンショット 2021-03-30 22.42.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/131473a0-c787-89fa-f257-a1b5c2d5f0a2.png)
|:

無事表示されてると思います。

#地名でmapを移動する（検索表示）
地名や住所を入力したら経度緯度を取得できるようにしたいと思います。
いわゆる、検索したら、その場所が表示される機能です。

**そういう機能をGeocoding(ジオコーディング)といいます。**

方法は2種類。

- GoogleのGeocoding APIを利用する。
- gemのgeocoderを利用する。

今回は、gemでいきたいと思います。

なお、Ajaxを使用します。

##Geocoding(Gemバージョン)
https://developers.google.com/maps/documentation/geocoding/overview?hl=ja

いつも通りgemfileに記述し、インストールしましょう。

```rb:Gemfile
gem 'geocoder'
```
```terminal:terminal
$ bundle install
```

次に、mapsコントローラーを記述します。
アクションに伴う、ルーティングも設定。

```rb:apps/controllers/maps_controller.rb
class MapsController < ApplicationController
  def index
  end

def map
  results = Geocoder.search(params[:address]) #viewで得た:addressをresultに変数に代入
  @latlng = results.first.coordinates #resultで得た情報をもとに緯度経度を取得する。
  
    respond_to do |format|
      format.js
    end
  end

end
```

```rb:routes.rb
resources :users, only:[:index]   
get '/map_request', to: 'maps#map', as: 'map_request' #追記
```

次に、viewsのmapsに「map.js.erb」を作成します。
![スクリーンショット 2021-03-30 22.56.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/905071aa-5dbd-f18c-3ea3-4e40b746c84a.png)

作成後は、ビューの記述です。

index.html.erb

```erb:app/views/maps/index.erb
<h2>gmap</h2>
<!-- form_withはデフォルトでremote: trueの挙動になります -->
<%= form_with url: map_request_path, method: :get do |f|%>　
  <%= f.text_field :address %> 
  <%= f.submit '地図表示' %>
<% end %>

<!--省略-->
```
map.js.erb

```erb:app/views/maps/map.js.erb
(function(){
  // 位置情報をもつ変数を用意
  let pos = new google.maps.LatLng(
   <%= @latlng[0] %>,  <!--配列の1個目が緯度-->
   <%= @latlng[1] %>   <!--配列の2個目が経度-->
  );

  mapInstance.setCenter(pos)
  let marker = new google.maps.Marker({
    map: mapInstance,　
    position: pos  <!--変数posで得た緯度経度が代入される-->
  });
})()
```
<details><summary>Map.setCenter()</summary><div>
Map.setCenter()はMapクラスのメソッドです。地図の位置座標をセットすると同時に、表示もその位置に変更されます。
</div></details>
----

#完成
検索した時の動きはこのようになってます。

|![スクリーンショット 2021-03-31 1.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/c186724c-a2b1-e0ae-b5c5-b1d992c2138a.png)
|:

```terminal:terminal
Processing by MapsController#map as JS
  Parameters: {"utf8"=>"✓", "address"=>"東京駅", "commit"=>"地図表示"}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
  ↳ /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.4.5/lib/active_record/log_subscriber.rb:98
  Rendering maps/map.js.erb
  Rendered maps/map.js.erb (1.4ms)
Completed 200 OK in 463ms (Views: 9.6ms | ActiveRecord: 1.3ms)
```

以上、たにーでした。

#参考文献

https://qiita.com/tiara/items/4a1c98418917a0e74cbb#%E5%9C%B0%E5%90%8D%E3%81%A7map%E3%82%92%E7%A7%BB%E5%8B%95%E3%81%99%E3%82%8B

https://qiita.com/momonoki1990/items/31390a355e2f6d24a81b

https://nendeb.com/276

https://qiita.com/tiara/items/573fe5f1a84ca57dabcd