簡単に実装できるはずのGoogleMapAPIですが数々の沼にハマったので細かく注意していきます。
環境
Rails 6.0.0
Ruby 2.6.5
EC2
Amazon Linux2
Nginx
mariaDB
Capistrano
機能
住所を入れると
DBに住所が保存、緯度経度が自動で算出されて
表示されます。
#Google Mapをアプリに埋め込む
Google Map API(サービス紹介ページ)
Google Map APIは、GoogleCloudのサービスのひとつで、GoogleCloudPlatformというコンソールから操作します、まずはそこで、Google Map javascript APIのAPIKeyを取得します。
GoogleCloudPlatformへ
☆Googleのアカウントがなければまずこちらから登録してください。
Googleアカウント登録
アカウントを作成したら(持っていたら)コンソールへ
https://console.cloud.google.com/
##プロジェクトを作成し、APIKeyを取得→地図表示
https://qiita.com/nagaseToya/items/e49977efb686ed05eadb
一連の流れはこちらにわかりやすく書かれています。
今回は、ここに加えて任意の住所記録、保存、出力します。
Geocording
緯度と経度を算出して、特定の位置を見つけてくれる機能です。gemのGeocoderと、Google CloudのGeocodeing APIというサービスを使います。
gemだけでも位置情報を取得することはできますが、「東京駅」では取得できても、「東京都〇〇区〇〇○○ー◯○」という具体的なアドレスでは取得できません。また取得できたりできなかったりします。そのためにより性能の良いGeocodeing APIも使えるようにします。
#コード
モデルは作成されているとします。(例Performancesモデル)
###①マイグレーションファイルを作成(カラム追加)
% rails g migration AddColumnsToPerformances
・入力された住所addressカラム
・geocodeによって自動で算出される緯度、経度カラム
class AddColumnsToPerformances < ActiveRecord::Migration[6.0]
def change
add_column :performances, :address, :string
add_column :performances, :latitude, :float
add_column :performances, :longitude, :float
end
end
% rails db:migrate
rollbackでもカラムは変更できますが、データが消えるのでなるべくadd_column(カラム追加)にすると良いと思います!
###②入力フォームの作成
保存先はaddressのみで大丈夫です。
<%= form_with(model: @performance, local: true) do |f| %>
***抜粋***
<label for="group-name">住所(GoogleMap表示)</label>
<span class="indispensable-any">任意</span>
<%= f.text_area :address,class:"new-performance-box", id:"gmap", placeholder:"Google Mapの住所をコピーして貼り付けてください" %>
***抜粋***
###③コントローラー
ストロングパラメーターでaddressを指定します。
before_action :set_performance, only: [:表示させるview]
def create
@performance = Performance.new(performance_params)
if @performance.valid?
@performance.save
redirect_to "/users/#{current_user.id}"
else
render :new
end
end
def 表示させるview
@performance = Performance.new(performance_params)
end
private
def set_performance
@performance = Performance.find(params[:id])
end
def performance_params
params.require(:performance).permit(:address).merge(user_id: current_user.id)
end
###④ビュー
CSSは別記してます。
zoomControl: false,
mapTypeControl: false,
fullscreenControl: false,
treetViewControl: false,
は拡大縮小ボタンなどを消す地図表示のオプションです。
<div id='map'>
<script>
let map
function initMap(){
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>},
zoom: 15,
zoomControl: false,
mapTypeControl: false,
fullscreenControl: false,
streetViewControl: false,
});
marker = new google.maps.Marker({
position: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>},
map: map
});
geocoder = new google.maps.Geocoder()
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAP_API'] %>&callback=initMap" async defer></script>
</div>
※key=<%= ENV['GOOGLE_MAP_API'] %>の表記は充分気をつけてください!ここで=の位置が違うだけで全てうまくいきません・・・
###⑤モデル
これでgeocordが緯度経度を算出してカラムに保存してくれます
geocoded_by :address
after_validation :geocode, if: :address_changed?
※if: :address_changed?がないと作用しないことがあるので気をつけてください!私はこれを書かないとダメでした
###⑥Geocording APIを使用するための記述
% rails generate geocoder:config
Geocoder.configure(
# Geocoding options
# timeout: 5, # geocoding service timeout (secs)
lookup: :google, # name of geocoding service (symbol)
# ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol)
# language: :en, # ISO-639 language code
use_https: true, # use HTTPS for lookup requests? (if supported)
# http_proxy: nil, # HTTP proxy server (user:pass@host:port)
# https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
api_key: 'YOUR_API_KEY', # API key for geocoding service
# cache: nil, # cache object (must respond to #[], #[]=, and #del)
# cache_prefix: 'geocoder:', # prefix (string) to use for all cache keys
# Exceptions that should not be rescued by default
# (if you want to implement custom error handling);
# supports SocketError and Timeout::Error
# always_raise: [],
# Calculation options
units: :km # :km for kilometers or :mi for miles
# distances: :linear # :spherical or :linear
)
#うまくいかない時の確認事項
・環境変数の設定
・viewの記述
・モデルのメソッド
・geocorder.rb
%rails c
[1] pry(main)> Geocoder.coordinates("〒150-0043 東京都渋谷区道玄坂2丁目1")
=> [35.6591376, 139.7007901]
で中身を変えながら出力されるか試してみる
・Google Map javascriptと、Geocoding APIのAPIkeyを一緒にしている場合、APIをもうひとつ作成し、別々にしてみる。
・本番環境での環境変数設定
[ec2-user@〜〜〜〜〜〜〜]$ sudo vim /etc/environment
変数設定後exit→再起動
[ec2-user@〜〜〜〜〜〜〜]$ env | grep YOUR_API_KEY
で確認
・EC2サーバーから再起動してみる(私はこれで最終的に本番環境で確認が取れました)