【WordPress】カフェ情報記事をGoogleMapでまとめて表示してみた

カフェ記事を書くようになりましたが、記事を見た人にわかりやすく、GoogleMapを表示したほうがいいかもと思い、追加してみました。
その方法についてまとめています。

実は近々仕事で似たようなことをやるかもしれないので、使い勝手の確認も兼ねています。

住所が分かればなんとかなるようにしたい

カフェ記事の最後には、『店舗名・住所・営業時間などの備考』といった店舗情報を書くようにしています。
この情報をそのままカスタムフィールドに追加するだけで、店舗情報の下に地図表示できるようにしたいと思います。

1)『Google Maps API Key』を取得します

Google Maps APIの使用には『API Key』が必要です。また、リクエスト数によっては、有料になるそうです。

取得方法についてはこちらのサイトがとてもわかりやすかったです。
【2018年度版】Google Maps の APIキー を簡単に取得する – ねんでぶろぐ

2)Advanced Custom Fieldsでカスタムフィールドを設定

記事の最後に出力するためのカスタムフィールドを設定します。
今回は使い勝手の良さから『Advanced Custom Fieldsプラグイン(ACF)』を追加。
そして、以下のように設定します。

お店の名前 ⇒ Cafe_Name
営業時間や定休日 ⇒ Cafe_Info
地図 ⇒ Cafe_Address

地図のCenterに設定している緯度経度は、投稿画面で表示される地図のCenterです。
デフォルトだとメルボルンになるので、東京駅(緯度:35.681167/経度:139.767052)にしました。

3)「Google Map」フィールドを使うために、API KEYを設定します

「Google Map」フィールドを設定しただけだと、投稿画面でこんな風にエラー表示されます。

使えるようにするため、テーマファイルの「functions.php」に以下を追加します。

// ACF用のAPI KEYを設定
function my_acf_google_map_api( $api ){
	$api['key'] = '{API_KEY}';
	return $api;
}
add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');

{API_KEY}の部分には(1)で取得したAPI Keyをいれてください。
すると、Mapが使えるようになります。

これで、地図を表示するために必要な「緯度」「経度」を取得&保存することができます。

今回自力で実装しようと頑張って断念した部分でもあります。
クリエイターでなくても、管理しやすいものを〜と考えた結果、これにたどり着きました。
(この件については後述します)

4)個別ページにカスタムフィールドの情報と地図を表示する

各テンプレートファイルを編集して、カフェ情報と地図を表示する記述を追加します。

functions.php

//GoogleMaps jsを追加 footer
function add_footer_enqueue_scripts_googlemaps_js() {
	echo '<script async defer src="https://maps.googleapis.com/maps/api/js?key={API_KEY}&callback=initMap"></script>';
}
add_action( 'wp_footer', 'add_footer_enqueue_scripts_googlemaps_js', 99 );

{API_KEY}の部分には(1)で取得したAPI Keyをいれてください。
これでGoogle Mapsを表示するためのスクリプトを、footerに追加することができます。
(footer.phpにwp_footerのフックが記述されている必要があります)

single.php

<?php
$location = get_field('Cafe_Address');
$map_address = $location['address'];
$map_lat = $location['lat'];
$map_lng = $location['lng'];
if ( $location ) : ?>
<h5>店舗情報</h5>
<div class="box">
<p><strong><?php echo post_custom('Cafe_Name'); ?></strong><br>
住所》<?php echo $map_address; ?><br>
<?php echo nl2br (post_custom('Cafe_Info')); ?></p>
<div id="map" style="width: 100%; height: 500px;"></div>
<script>
function initMap() {
	var lockpin = new google.maps.LatLng(<?php echo $map_lat; ?>, <?php echo $map_lng; ?>);
	var map = new google.maps.Map(document.getElementById('map'), {
		zoom: 18,
		center: lockpin,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		scaleControl: true
	});
	var marker = new google.maps.Marker({
		icon: 'http://maps.google.co.jp/mapfiles/ms/icons/blue-pushpin.png',
		position: lockpin,
		map: map,
	});
}
</script>
</div>
<?php endif; ?>

Map機能の「緯度」と「経度」は、3〜4行目の部分で取得しています。
['address']で住所のテキスト情報を、['lat']で緯度、['lng']で経度を取得できます。

また、22行目部分の画像URLを変更するとオリジナルのピン画像に変更できます。

カフェをまとめて1つの地図で表示

記事にしたカフェを、1つの地図上でまとめて表示できるページも作りました。
カフェ巡りしたい時にまとめて見れたら便利なので。

ソース

まずまとめた地図を表示するためのショートコードを作る関数をfunctions.phpに追加します。

functions.php

// 地図まとめ用ショートコード
function allMapFunc($atts) {
	extract(shortcode_atts(array(
		'tagname' => 'カフェ',
	), $atts));
	global $wpdb;
	global $post;
	$map_html = '<div id="map" style="width: 100%; height: 500px;"></div>'."\n";
	$map_html .= '<script>';
	$map_html .= 'var map; var marker = []; var infoWindow = [];'."\n";
	$map_html .= 'var markerData = ['."\n";
	$map_links = "";
	$map_post = get_posts(array('posts_per_page' => 100,'post_type' => 'post','post_status' => 'publish,future,draft','tax_query' => array(array('taxonomy' => 'post_tag','field' => 'slug','terms' => $tagname))));
	if($map_post){
		foreach($map_post as $post) : setup_postdata( $post );
		$location = get_field('Cafe_Address');
		$map_address = $location['address'];
		$map_lat = $location['lat'];
		$map_lng = $location['lng'];
		$map_links .= '{name: \'<a href="'.get_the_permalink().'">'.get_the_title().'</a>\','."\n";
		$map_links .= 'lat: '.$map_lat.','."\n";
		$map_links .= 'lng: '.$map_lng.','."\n".'},'."\n";
		endforeach;
	}else{
		$map_links ="データなし";
	}
	wp_reset_postdata();
	$map_html .= $map_links;
	$map_html .= <<<EOT
];
function initMap() {
	var mapLatLng = new google.maps.LatLng({lat: 35.658581, lng: 139.745433});
	map = new google.maps.Map(document.getElementById("map"), { center: mapLatLng, zoom: 12 });
	for (var i = 0; i < markerData.length; i++) {
		markerLatLng = new google.maps.LatLng({lat: markerData[i]['lat'], lng: markerData[i]['lng']});
		marker[i] = new google.maps.Marker({ 
			icon: "http://maps.google.co.jp/mapfiles/ms/icons/blue-pushpin.png",
			position: markerLatLng,
			map: map
		});
		infoWindow[i] = new google.maps.InfoWindow({
			content: '<div class="sample">' + markerData[i]['name'] + '</div>'
		});
		markerEvent(i);
	}
}
function markerEvent(i) {
	marker[i].addListener('click', function() {infoWindow[i].open(map, marker[i]);});
}
</script>
EOT;
	return $map_html;
}
add_shortcode('allMapPin', 'allMapFunc');

あとは任意のページで[allMapPin tagname="純喫茶"]と記載するだけで、「純喫茶」タグのついた記事の地図情報(緯度/経度)のピンをつけた、地図が表示されます。
ピンをクリックすると、小さな吹き出しが開き、ピン情報に紐付いた記事が表示される仕組みです。

ちなみにこんな感じです(スクショです)。

実際に動いてるページはこちら

4行目のタグ名はショートコードの引数「tagname」を指定しなかった時のデフォルトの値になります。
15〜23行目部分で指定されたタグのついた記事情報を取得&ピンの追加を行っています。

また、20行目、部分でクリックで開く吹き出し部分の内容を変更できますよ。

余談

もともとは Google Maps Geocoding APIを使ってやろうと思ったのですが、以下の点から断念しました。

  • Google Mapを、Geocoding APIで取得した緯度経度を使って表示したらズレてしまう。
  • 測地系が色々あり、修正をする必要がある。
  • 計算式をいくつか試してみたが、うまくいかなかった(誤差が直らない…)
  • 考えていた仕様だと、Mapを表示するために毎回Geocodingで緯度経度を取得し直すことになる(API上限をすぐ超える)
  • 記事ごとに緯度経度を保存しておきたいが、手動ではない方法がちょっと思いつかなかった。
  • ACFを使えば、悩んでいる上記の問題も簡単に解決できると分かったらやる気が…。

とはいえ、遠回りはしたものの、大変勉強になりました。
WPを使わずにやる必要が出てきたら、もっと掘り深めてみようと思います( ˘ω˘)

参考サイト

UPDATE : / Tags

人気のタグ:ゲームAjax寝かしつけcookieお金の話やってみた雑記Map子どもとおでかけCUD(カラーユニバーサルデザイン)

関連記事

新着記事

コメントを残す