はじめに
つくるもの
こんな感じの投稿した住所または地名から緯度と経度を所得してそれぞれの地点にマーカーを立てるマップです。
(「東京都墨田区押上1丁目1−2」(スカイツリー)のように住所を投稿することも可能です)
用意しておくもの
前提知識
今回はGoogleMapAPIを用いたマップの表示はできているものとして進めていきます。
必要なAPI
・Maps JavaScript API
・Geocoding API
GoogleMapAPIを用いたマップの表示がわからない人は下記の記事をお読みください。
上記APIの導入方法とマップの表示方法が書いてあります。
【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
機能
シンプルな投稿機能は用意しておいてください。
筆者は住所や地名を投稿するためのaddressカラムを持った、mapsテーブルを作りました。
こんな感じです!
流れ
- 緯度・経度を保存するためのlatitudeカラムとlongitudeカラムをmapsテーブルに追加する。
- Geocoderを利用して、入力された住所または地名から緯度・経度を取得しそれぞれをlatitudeカラムとlongitudeカラムに保存できるようにする。
- 投稿された緯度・経度の地点にマーカーを立てる。
実装
上記の流れに沿って実装していきます!
###1. カラム追加
$ rails g migration AddCoordinateToMaps latitude:float longitude:float
上記コマンドでlatitude
とlongitude
の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
class Map < ApplicationRecord
geocoded_by :address
after_validation :geocode
end
:address
の部分にはGeocodingを行いたいカラムを書きます。
この2行をaddress
、latitude
、longitude
を持ったモデルに対して記述してあげると、address
に入力された住所や地名から緯度・経度を取得しそれぞれのカラムに保存してくれます。
そして一覧画面でlatitude
とlongitude
を表示してあげると以下のように緯度と経度がそれぞれ表示されるようになったと思います。
しかし、このままでは「東京都墨田区押上1丁目1−2」のように住所を投稿すると緯度と経度は取得できません。
geocoder用のコンフィグファイルを作成
以下のコマンドでコンフィグファイルを作成。
$ rails g geocoder:config
config/initializers/geocoder.rbというコンフィグファイルが生成されるので、そのファイルにgooglemapのAPI情報を記載します。
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
の中のtimeout
、lookup
、api_key
、units
の4つの項目のコメントアウトを外し、必要事項を上記コードのように記入する。
こうすることで詳細度の高い住所もgeocoderが取得してくれるようになる。
###3. 投稿された位置にマーカーを表示する
<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に代入していますが、このように複数回使いそうな情報は変数に代入しておくと便利です。(吹き出しなどを追加で実装する際に使うことがあります。)
デプロイするときはちゃんとAPIキーは.envファイルに記入しgitignoreファイルに隠すようにしましょうね!
じゃないとあなたのAPIキーは全世界の人に丸見えになっちゃいますよ!
自分の身は自分で守ろう
参考記事
- RailsのGeocoderとあそぼ
- 【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
- [Rails5でGoogleMapsAPIを用い、複数のマーカーを表示する](https://qiita.com/yamaotoko4177/items/30b72766d013904452fa
86ed05eadb "マップ表示について") - [Ruby on RailsとGoogle Geocoding APIで住所から緯度・経度を取得する方法](https://programming-beginner-zeroichi.jp/articles/271
86ed05eadb "マップ表示について")