Google map apiを使って住所を検索して表示できるようにした
Google map apiの利用
こちらの記事を参考にしました。
Google Maps API を使ってみた
"Maps JavaScript API”を利用してGoogle Mapをページに埋め込む方法
- googleアカウントを作成
- Google Cloud Pratformにアクセスし、プロジェクトを作成
- Map JavaScript APIを有効化し、APIキーを取得
### 試してみる
html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Sample_GoogleMap</title>
<script src="http://maps.google.com/maps/api/js?key=YOUR_KEY&language=ja"></script>
<style>
html { height: 100% }
body { height: 100% }
#map { height: 100%; width: 100%}
</style>
</head>
<body>
<div id="map"></div>
<script>
var MyLatLng = new google.maps.LatLng(35.6811673, 139.7670516);
var Options = {
zoom: 15, //地図の縮尺値
center: MyLatLng, //地図の中心座標
mapTypeId: 'roadmap' //地図の種類
};
var map = new google.maps.Map(document.getElementById('map'), Options);
</script>
</body>
</html>
API_Keyを環境変数にする
Gemfile
gem 'dotenv-rails'
ターミナル
bundle install
.envファイル
を手動で作成する
.env
GoogleMap_API_Key = YOUR_Key
.gitignore
/.env
showページに合わせて動的に地図を変更する
- Geocording APIを有効化する
View
institution_map.html.erb
〜略〜
<div class="institution_show_address_container">
<div class="institution_show_address_label show_label">住所</div>
<%#- 表示元の住所 -%>
<div class="institution_show_address_text show_text", id="institution_mapping_address"><%= institution.address %></div>
</div>
〜略〜
<div class="map_container">
<%# マップを表示する場所 %>
<div id='institution_map'></div>
</div>
<script>
let map
let geocoder
<%# ページ呼出し時の処理 %>
function initMap(){
geocoder = new google.maps.Geocoder()
<%# 表示住所を取得 %>
let putAddress = document.getElementById('institution_mapping_address').textContent;
geocoder.geocode( { 'address': putAddress}, function(results, status) {
if (status == 'OK') {
<%# 表示場所にマップを表示 %>
map = new google.maps.Map(document.getElementById('institution_map'), {
zoom: 17,
});
map.setCenter(results[0].geometry.location);
<%# マップにマーカーを表示 %>
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('該当する結果がありませんでした:' + status);
}
});
}
</script>
<%# ページを表示するときにinitMapを動作させる %>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GoogleMap_API_KEY'] %>&callback=initMap" async defer></script>
住所を検索して地図を表示できるようにする
search_address.html.erb
<div class="search_map_container">
<h2>医療機関を検索</h2>
<%# 検索したい住所や場所を入力するテキストボックス %>
<input id="search_address" type="textbox" value="GeekSalon">
<%# 処理を行うボタン %>
<input id="search_address_button", type="button" value="検索" onclick="codeAddress()">
<div>
<%# 住所を表示する %>
<div id="result_address">住所が表示されます</div>
</div>
<%# 地図を表示する %>
<div id='search_map'></div>
</div>
<script>
let map
let geocoder
<%# 初期化処理 %>
function initMap(){
geocoder = new google.maps.Geocoder()
<%# 参考にする住所がないので初期設定を行う。 lat:緯度、lng:経度。サンプルは東京駅 %>
map = new google.maps.Map(document.getElementById('search_map'), {
center: {lat: 35.6809591, lng: 139.7673068},
zoom: 15,
});
<%# マーカーを配置 %>
marker = new google.maps.Marker({
position: {lat: 35.6809591, lng: 139.7673068},
map: map
});
}
<%# ボタンを押した時の処理 %>
function codeAddress(){
<%# 検索したいアドレスを取得 %>
let inputAddress = document.getElementById('search_address').value;
geocoder.geocode( { 'address': inputAddress}, function(results, status) {
if (status == 'OK') {
<%# マップを表示
map.setCenter(results[0].geometry.location);
<%# 検索で得られた住所を取得 %>
result_address = results[0].formatted_address;
<%# 取得した住所を表示 %>
document.getElementById('result_address').textContent = result_address
<%# マーカーを表示 %>
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('該当する結果がありませんでした:' + status);
}
});
}
</script>
<%# 初期設定処理 %>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GoogleMap_API_KEY'] %>&callback=initMap" async defer></script>
周辺の施設を表示する
place_map.html.erb
<%# 初期住所 %>
<div class="place_medicalstaff_address"></div>
<%# 地図表示部分 %>
<div class="place_map_container">
<h2>周辺の医療機関検索</h2>
<div class="place_map_search_area">
<%# 検索したい住所を入力 %>
<input type="text" size="55" id="place_search">
<%# 処理するボタン %>
<input type="button" size="55" value="検索" id="place_search_button" onClick="SearchGo()">
</div>
<div id="place_map style="width: 300px; height: 300px;">"></div>
</div>
<%# 先にapiへアクセスしないと、googleメソッドがエラーになる %>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GoogleMap_API_KEY'] %>&libraries=places"></script>
<script>
var myMap;
var service;
<%# 初期処理 %>
function initialize() {
geocoder = new google.maps.Geocoder()
<%# 初期住所の場所を取得する %>
let defaultAddress = document.getElementById('place_medicalstaff_address').textContent;
geocoder.geocode( { 'address': defaultAddress}, function(results, status) {
if (status == 'OK') {
<%# 取得した住所情報からmapを表示 %>
let lat = results[0].geometry.location.lat();
let lng = results[0].geometry.location.lng();
var initPos = new google.maps.LatLng(lat, lng);
<%# オプション(MapOptionクラス)で地図のプロパティを設定(倍率、マーカー表示位置、地図の種類) %>
var myOptions = {
zoom: 15,
center: initPos,
};
myMap = new google.maps.Map(document.getElementById("place_map"), myOptions);
<%# 検索の条件を指定(緯度経度、半径、検索の分類) %>
var request = {
location: initPos,
radius: 1000, <%# ※1 表示する半径領域を設定(1 = 1M) %>
types: ['hospital'] <%# ※2 typesプロパティの施設タイプを設定 %>
};
<%# placeAPIを使用して周辺情報を取得する %>
var service = new google.maps.places.PlacesService(myMap);
service.search(request, Result_Places);
} else {
alert('該当する結果がありませんでした:' + status);
}
});
}
<%# 検索結果を受け取る %>
function Result_Places(results, status){
<%# Placesが検索に成功したかとマうかをチェック %>
if(status == google.maps.places.PlacesServiceStatus.OK) {
<%# 検索結果の数だけ反復処理を変数placeに格納 %>
for (var i = 0; i < results.length; i++) {
var place = results[i];
<%# 定義したcreateMarker関数で、取得したplaceにマーカーを表示 %>
createMarker({
text : place.name,
position : place.geometry.location
});
}
}
}
<%# 検索フォームから検索したとき %>
function SearchGo() {
geocoder = new google.maps.Geocoder()
<%# 検索したい住所を受け取る %>
let defaultAddress = document.getElementById('place_search').value;
geocoder.geocode( { 'address': defaultAddress}, function(results, status) {
if (status == 'OK') {
let lat = results[0].geometry.location.lat();
let lng = results[0].geometry.location.lng();
var initPos = new google.maps.LatLng(lat, lng);
var myOptions = {
center : initPos,
zoom: 15
};
myMap = new google.maps.Map(document.getElementById("place_map"), myOptions);
var request = {
location: initPos,
radius: 1000,
types: ['hospital']
};
var service = new google.maps.places.PlacesService(myMap);
service.search(request, Result_Places);
} else {
alert('該当する結果がありませんでした:' + status);
}
});
}
<%# 検索フォームで検索した場合の、map検索結果を受け取る %>
function result_search(results, status) {
var bounds = new google.maps.LatLngBounds();
for(var i = 0; i < results.length; i++){
createMarker({
position : results[i].geometry.location,
text : results[i].name,
map : myMap
});
bounds.extend(results[i].geometry.location);
}
<%# Map.fitBounds()で、マーカーの場所を全て表示するように地図のビューポート(位置座標とズーム値)を変更 %>
myMap.fitBounds(bounds);
}
<%# 該当する位置にマーカーを表示 %>
function createMarker(options) {
<%# マップ情報を保持しているmyMapオブジェクトを指定 %>
options.map = myMap;
<%# Markcrクラスのオブジェクトmarkerを作成 %>
var marker = new google.maps.Marker(options);
<%# 各施設の吹き出し(情報ウインドウ)に表示させる処理 %>
var infoWnd = new google.maps.InfoWindow();
infoWnd.setContent(options.text);
<%# addListenerメソッドを使ってイベントリスナーを登録 %>
google.maps.event.addListener(marker, 'click', function(){
infoWnd.open(myMap, marker);
});
return marker;
}
<%# ページ読み込み完了後、Googleマップを表示 %>
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Turbolinks
viewにscript
を記述する場合は、Turbolinksを切る方がいいらしい。
views/layouts/application.html.erb
<%= link_to "home", root_path, "data-turbolinks": false %>
全部切る場合は、app/javascript/application.js
、Gemfile
などから、Turbolinksを削除すればOK(非推奨)
参考記事
Google Maps API の使い方・利用方法
【Google MAP】名称から場所を検索・特定する
Google Maps APIで住所から緯度経度を求める
【Rails6 / Google Map API】初学者向け!Ruby on Railsで簡単にGoogle Map APIの導入する
GoogleMapsAPIでマップで施設検索してやんよ!!!
Google API 第8回
SYNCER (Google Maps API)
Rails Turbolinksをページ毎に無効化する方法