LoginSignup
4
1

More than 3 years have passed since last update.

【Rails6 / Google Map API】住所を投稿してマップに複数マーカーを立てる (モデルを介さないver.)

Last updated at Posted at 2021-02-04

つくるもの

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

用意しておくもの

前提知識

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

必要なAPI
・Maps JavaScript API
・Geocoding API

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

機能

シンプルな投稿機能は用意しておいてください。
私は住所や地名を投稿するためのaddressカラムを持った、mapsテーブルを作りました。

スクリーンショット 2021-02-04 15.49.12.png
こんな感じです!

流れ

  1. マーカーを立てるために、投稿されたaddressから緯度・経度を取得するための記述をscriptタグ内に加える。
  2. 取得した緯度・経度から投稿分のマーカーを立てる。

ざっとこれだけです!非常に簡単ですね!
それでは早速やっていきましょう!

実装

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

1. 緯度・経度の取得

緯度・経度を取得するにはGeocodingを行います。

Geocoding

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

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

必要なgemをインストール

gem 'geocoder'

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

$ bundle install

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

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

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が取得してくれるようになる。

では、実際に実装しましょう!

index.html.erb
<div id="map"></div>
<script>
    let map;
        function initMap() {
            map = new google.maps.Map(document.getElementById("map"), {
                center:{lat: 35.68123620000001, lng:139.7671248},
                zoom: 12,
            });
        }
</script>

<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLEMAPS_API_KEY'] %>&callback=initMap" async defer>
</script>

もともとのscriptタグがこれ。
そこに以下の内容を付け加えることで各投稿から緯度・経度を取得することができます。

index.html.erb
<div id="map"></div>
<script>
    let map;
        function initMap() {
            map = new google.maps.Map(document.getElementById("map"), {
                center:{lat: 35.68123620000001, lng:139.7671248},
                zoom: 12,
            });
            // ここから
            <% @maps.each do |m| %>
                <% results = Geocoder.search(m.address) %>
                <% if results.present? %>
                    <% @latlng = results.first.coordinates %>

                <% end %>
            <% end %>
            // ここまで
        }
</script>

これで各投稿の緯度・経度が@latlngに代入されました。
次はこの@latlngを使ってそれぞれの地点にマーカーを立てていこう!

2.マーカーを立てよう!

1で緯度・経度の取得はできたのであとはその地点にマーカーを立てる記述をするだけです!
以下の記述を加えてください。

index.html.erb
<div id="map"></div>
<script>
    let map;
        function initMap() {
            map = new google.maps.Map(document.getElementById("map"), {
                center:{lat: 35.68123620000001, lng:139.7671248},
                zoom: 12,
            });
            <% @maps.each do |m| %>
                <% results = Geocoder.search(m.address) %>
                <% if results.present? %>
                    <% @latlng = results.first.coordinates %>
                    // ここから
                    (function() {
                        let marker = new google.maps.Marker({
                            position:{lat: <%= @latlng[0] %>, lng: <%= @latlng[1] %>},
                            map: map
                        });
                    })();
                    // ここまで
                <% end %>
            <% end %>
        }
</script>

<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLEMAPS_API_KEY'] %>&callback=initMap" async defer></script>

すると、、、
スクリーンショット 2021-02-04 16.40.23.png

このようにマップにマーカーが立ちました。
以上。

(turbolinksを無効にしてあげないと特に詳細度の高い住所のマーカーは立たないかもです。)

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

参考記事

4
1
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
4
1