14
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails6 / Google Map API】住所を投稿してマップに複数マーカーを立てる

Last updated at Posted at 2020-09-04

はじめに

つくるもの

こんな感じの投稿した住所または地名から緯度と経度を所得してそれぞれの地点にマーカーを立てるマップです。
(「東京都墨田区押上1丁目1−2」(スカイツリー)のように住所を投稿することも可能です)
スクリーンショット 2020-08-28 1.54.39.png

用意しておくもの

前提知識

今回はGoogleMapAPIを用いたマップの表示はできているものとして進めていきます。

必要なAPI
・Maps JavaScript API
・Geocoding API

GoogleMapAPIを用いたマップの表示がわからない人は下記の記事をお読みください。
上記APIの導入方法とマップの表示方法が書いてあります。
【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する

機能

シンプルな投稿機能は用意しておいてください。
筆者は住所や地名を投稿するためのaddressカラムを持った、mapsテーブルを作りました。
スクリーンショット 2020-08-29 16.41.46.png
こんな感じです!

流れ

  1. 緯度・経度を保存するためのlatitudeカラムとlongitudeカラムをmapsテーブルに追加する。
  2. Geocoderを利用して、入力された住所または地名から緯度・経度を取得しそれぞれをlatitudeカラムとlongitudeカラムに保存できるようにする。
  3. 投稿された緯度・経度の地点にマーカーを立てる。

実装

上記の流れに沿って実装していきます!

###1. カラム追加

$ rails g migration AddCoordinateToMaps latitude:float longitude:float

上記コマンドでlatitudelongitudeの2つのカラムを追加するためのマイグレーションファイルを作成します。

$ rails db:migrate

忘れずにマイグレートしましょう!

###2. Geocoderを利用して緯度・経度を取得する

Geocoding

  • Q. そもそもGeocodingとは??
  • A. 住所や地名から座標(緯度・経度)を取得したり、座標から住所や地名を取得すること。
    またIPアドレスからも住所や地名を取得することもできる。

ちなみに下記の記事はGeocodingに関して詳しく書いてくれているのでもっと詳しく知りたい人は是非ご覧ください。
RailsのGeocoderとあそぼ

必要なgemをインストール

gem 'geocoder'

上記のコードをgemファイルの中に記述する。

$ bundle install

しっかりとbundle installを行いましょう〜!
これでrailsの中でgeocoderを使用することができます。

モデルに対するGeocoding

map.rb
class Map < ApplicationRecord
    geocoded_by :address
    after_validation :geocode
end

:addressの部分にはGeocodingを行いたいカラムを書きます。
この2行をaddresslatitudelongitudeを持ったモデルに対して記述してあげると、addressに入力された住所や地名から緯度・経度を取得しそれぞれのカラムに保存してくれます。

そして一覧画面でlatitudelongitudeを表示してあげると以下のように緯度と経度がそれぞれ表示されるようになったと思います。

スクリーンショット 2020-08-29 18.15.22.png

しかし、このままでは「東京都墨田区押上1丁目1−2」のように住所を投稿すると緯度と経度は取得できません。

geocoder用のコンフィグファイルを作成

以下のコマンドでコンフィグファイルを作成。

$ rails g geocoder:config

config/initializers/geocoder.rbというコンフィグファイルが生成されるので、そのファイルにgooglemapのAPI情報を記載します。

config.initializers.geocoder.rb
Geocoder.configure(
  # Geocoding options
  timeout: 5,                 # geocoding service timeout (secs)
  lookup: :google,         # name of geocoding service (symbol)
  api_key: 'YOUR_API_KEY',               # API key for geocoding service
  units: :km,                 # :km for kilometers or :mi for miles
)

生成されたgeocoder.rbの中のtimeoutlookupapi_keyunitsの4つの項目のコメントアウトを外し、必要事項を上記コードのように記入する。

こうすることで詳細度の高い住所もgeocoderが取得してくれるようになる。

###3. 投稿された位置にマーカーを表示する

index.html.erb


<div id='map'></div>

<script>
  let map

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

      map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 35.68123620000001, lng:139.7671248},
          zoom: 12,
      });


      <% @maps.each do |m| %>
          (function(){
          var contentString = "住所:<%= m.address %>"; 

          var marker = new google.maps.Marker({
              position:{lat: <%= m.latitude %>, lng: <%= m.longitude %>},
              map: map,
              title: contentString
          });

          })();
      <% end %>
      }
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>

上記コードのように<% @maps.each do |m| %> ~ <% end %>の中に繰り返し処理を行いたいコードを書くと投稿した住所や地名の位置にマーカーが立つようになります。
※住所をcontentStringに代入していますが、このように複数回使いそうな情報は変数に代入しておくと便利です。(吹き出しなどを追加で実装する際に使うことがあります。)
スクリーンショット 2020-09-12 15.24.22.png

デプロイするときはちゃんとAPIキーは.envファイルに記入しgitignoreファイルに隠すようにしましょうね!
じゃないとあなたのAPIキーは全世界の人に丸見えになっちゃいますよ!
自分の身は自分で守ろう:thumbsup:

参考記事

14
23
0

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
14
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?