LoginSignup
30

More than 3 years have passed since last update.

【Rails】Geocoding APIを用いて高精度で緯度経度を算出し、Google Mapに表示する方法

Last updated at Posted at 2020-06-03

目標

ユーザーが登録した住所をマップの中心に表示し、マーカーを立てる。
ezgif.com-video-to-gif (1).gif

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

Slim導入
ログイン機能実装
Google Map表示

gem 'geocoder'だけでは精度が低い(番地指定が出来ない地域がある)為、
Geocoding APIを使用して高精度で住所から緯度経度を特定出来る様に実装していきます。

Geocoding API有効化

1.下記リンクにアクセス

Google Cloud Platform

2. 「APIの概要に移動」をクリック

スクリーンショット 2020-06-03 10.01.36.png

3.「ライブラリ」をクリック

スクリーンショット 2020-06-03 10.01.41.png

4.検索フォームに「geo」と入力し、「Geocoding API」をクリック

スクリーンショット 2020-06-03 10.02.08.png

5.「有効にする」をクリック

スクリーンショット 2020-06-03 10.02.13.png

6.赤枠で囲われている箇所をクリック

スクリーンショット 2020-06-03 10.02.31.png

7.プルダウンメニューが表示されるので、「全てのGoogle Maps API」をクリック

スクリーンショット 2020-06-03 10.04.02.png

8.「認証情報」をクリック

スクリーンショット 2020-06-03 10.12.39.png

9.「APIキーの名前」をクリック

スクリーンショット 2020-06-03 10.12.46.png

10.認証情報の設定をする

①APIの制限
キーを制限を選択し、プルダウンメニューからGeocoding APIを選択する。

Maps JavaScript APIと、Geocoding APIが選択されている事を確認して、保存をクリック

スクリーンショット 2020-06-03 10.13.14.png

11.APIが2個になっているかを確認

APIを追加した事でAPIキーが変更されるという事は無いので、これで完了。

スクリーンショット 2020-06-03 10.13.25.png

実装

1.Gemを導入

Gemfile
gem 'gon'
gem 'geocoder'

gem 'gon'
➡︎ コントローラーで定義したインスタンス変数をビューのJavaScript内で使用出来る様にする。

gem 'geocoder'
➡︎ 住所から緯度経度を算出する。

ターミナル
$ bundle

2.geocorderの設定ファイルを作成し、編集

ターミナル
$ touch config/initializers/geocoder.rb
geocoder.rb
# 追記
Geocoder.configure(
  lookup: :google,
  api_key: ENV['GOOGLE_MAP_API']
)

これでGeocoding APIを使用する事ができ、緯度経度の算出が高精度で行えます。

3.カラムを追加

ターミナル
$ rails g migration AddColumnsToUsers address:string latitude:float longitude:float
add_columns_to_users.rb
class AddColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :address, :string
    add_column :users, :latitude, :float
    add_column :users, :longitude, :float
  end
end
ターミナル
$ rails db:migrate

4.モデルを編集

user.rb
  # 追記
  geocoded_by :address
  after_validation :geocode

geocoded_by :address
➡︎ addressカラムを基準に緯度経度を算出する。

after_validation :geocode
➡︎ 住所変更時に緯度経度も変更する。

5.コントローラーを編集

application_controller.rbを編集

ストロングパラメーターに「address」を追加します。

application_controller.rb
def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :address])
end

users_controller.rbを編集

users_controller.rb
def show
  @user = User.find(params[:id])
  gon.user = @user # 追記
end

6.ビューを編集

application.html.slimを編集

gonを読み込みます。
CSSとJavaScriptより先に読み込んでいる事に注意して下さい。

application.html.slim
doctype html
html
  head
    title
      | Bookers2
    = csrf_meta_tags
    = csp_meta_tag
    = include_gon # 追記
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'

②新規会員登録画面に住所入力フォームを追加

resistrations/new.html.slim
= f.label :address, '住所'
br
= f.text_field :address, class: 'form-control'
br

③マップを編集

users/show.html.erb
#map style='height: 500px; width: 500px;'

- google_api = "https://maps.googleapis.com/maps/api/js?key=#{ ENV['GOOGLE_MAP_API'] }&callback=initMap".html_safe
script{ async src=google_api }

javascript:

  let map;

  function initMap() {
    geocoder = new google.maps.Geocoder()

    map = new google.maps.Map(document.getElementById('map'), {
      // コントローラーで定義した変数から緯度経度を呼び出し、マップの中心に表示
      center: {
        lat: gon.user.latitude,
        lng: gon.user.longitude
      },
      zoom: 12,
    });

    marker = new google.maps.Marker({
      // コントローラーで定義した変数から緯度経度を呼び出し、マーカーを立てる
      position: {
        lat: gon.user.latitude,
        lng: gon.user.longitude
      },
      map: map
    });
  }

注意

turbolinksを無効化しないと地図が切り替わらないので、必ず無効化しておきましょう。

turbolinksを無効化する方法

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30