つくるもの
こんな感じの投稿した住所または地名から緯度と経度を取得して各投稿の地点にマーカーを立てるマップです。
(「東京都墨田区押上1丁目1−2」(スカイツリー)のように住所を投稿することも可能です)
用意しておくもの
前提知識
今回はGoogleMapAPIを用いたマップの表示はできているものとして進めていきます。
必要なAPI
・Maps JavaScript API
・Geocoding API
GoogleMapAPIを用いたマップの表示がわからない人は下記の記事をお読みください。
上記APIの導入方法とマップの表示方法が書いてあります。
【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
機能
シンプルな投稿機能は用意しておいてください。
私は住所や地名を投稿するためのaddressカラムを持った、mapsテーブルを作りました。
流れ
- マーカーを立てるために、投稿された
address
から緯度・経度を取得するための記述をscriptタグ内に加える。 - 取得した緯度・経度から投稿分のマーカーを立てる。
ざっとこれだけです!非常に簡単ですね!
それでは早速やっていきましょう!
実装
上記の流れに沿って実装していきます!
###1. 緯度・経度の取得
緯度・経度を取得するにはGeocodingを行います。
Geocoding
- Q. そもそもGeocodingとは??
- A. 住所や地名から座標(緯度・経度)を取得したり、座標から住所や地名を取得すること。
またIPアドレスからも住所や地名を取得することもできる。
ちなみに下記の記事はGeocodingに関して詳しく書いてくれているのでもっと詳しく知りたい人は是非ご覧ください。
RailsのGeocoderとあそぼ
必要なgemをインストール
gem 'geocoder'
上記のコードをgemファイルの中に記述する。
$ bundle install
しっかりとbundle install
を行いましょう〜!
これでrailsの中でgeocoderを使用することができます。
しかし、このままでは「東京都墨田区押上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が取得してくれるようになる。
では、実際に実装しましょう!
<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タグがこれ。
そこに以下の内容を付け加えることで各投稿から緯度・経度を取得することができます。
<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で緯度・経度の取得はできたのであとはその地点にマーカーを立てる記述をするだけです!
以下の記述を加えてください。
<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>
このようにマップにマーカーが立ちました。
以上。
(turbolinksを無効にしてあげないと特に詳細度の高い住所のマーカーは立たないかもです。)
デプロイするときはちゃんとAPIキーは.envファイルに記入しgitignoreファイルに隠すようにしましょうね!
じゃないとあなたのAPIキーは全世界の人に丸見えになっちゃいますよ!
自分の身は自分で守ろう