GoogleMapAPIがV3になりまして、任意に地図上にプロットするのが少し簡単になった?気がします。wordpressのエントリーに緯度経度をカスタムフィールドとして持たせて、それをプロットするというのを試してみたので、メモ。
以下、実際に使ったコード(から、ある程度値を変えたもの)です。
あ。あらかじめ記事のほうで「Lat_Long」という名称でカスタムフィールドの緯度経度を持たせている前提です。
※プラグイン等で簡単に設定できます。
WordPress(ワードプレス)の投稿画面で簡単にGoogleMapを挿入するプラグイン(Google Maps Anywhere)
//マップを表示するための空div
<div id="map_canvas" style="width:680px;height:300px"></div>
//api呼び出し
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript">
var myMap;//マップ定義用変数
var myLat = [];//座標格納用変数
function initialize() {//マップを表示する関数 onloadで呼び出し
var latlng = new google.maps.LatLng(35.685326,139.753132);//マップの中心とする緯度経度設定
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
myMap = new google.maps.Map(document.getElementById("map_canvas"), myOptions);//マップを定義
setMarkers(myMap, markers);//マップにマーカーを配置する関数(中身は後述)
}
//マーカーの吹き出しに内容を入れる関数
function attachMessage(marker, msg) {
google.maps.event.addListener(marker, 'click', function(event) {
new google.maps.InfoWindow({
content: msg
}).open(marker.getMap(), marker);
});
}
//指定した緯度経度にマップを移動させる関数
function toMarker(num) {
myMap.panTo(myLat[num]);
}
//ここからWordPressとの絡み。一部php
<?php
//query_postsのクエリを設定
$args = array(
'post_type' => 'ポストタイプ名',
'order' => 'ASC'
);
query_posts( $args );
$flag = 0;
?>
//マーカーの基本情報をセット
var markers = [
<?php
if(have_posts()):while(have_posts()):the_post();
//カスタムフィールドの値読み込み
$lat = get_post_meta($post->ID, 'Lat_Long', true);
$npos = get_post_meta($post->ID, 'author_id',true);
$lat = get_post_meta($post->ID, 'Lat_Long', true);
$markerUrl = get_bloginfo('url').'?author='.$npos;
if($flag != 0 ){
echo ',';
}
?>
['<?php the_title(); ?>',<?php echo $lat; ?>, <?php echo $npos; ?>,'<?php echo $markerUrl; ?>','<?php the_post_thumbnail(); ?>'],
<?php
$flag++;
endwhile;endif;wp_reset_query();
?>
];
//マーカー一覧の設定から、マップにマーカーをプロットする関数
function setMarkers(map, locations) {
// ドロップシャドウ用画像定義
var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
new google.maps.Point(0,0),
new google.maps.Point(0, 52));
// 実際にクリックさせる範囲 htmlのクリッカブルマップ表記にて指定
var shape = {
coord: [1, 1, 26, 52],
type: 'rect'
};
//以下マーカーを配置する処理
for (var i = 0; i < locations.length; i++) {
var npo = locations[i];
var image = new google.maps.MarkerImage('<?php bloginfo('template_url'); ?>/images/marker_'+npo[3]+'.png',
// マーカー画像のサイズ
new google.maps.Size(26, 52),
// 画像の本来の基点
new google.maps.Point(0,0),
// マーカー画像が指し示すポイントとしたい点(画像の基点を元としたピクセル数)
new google.maps.Point(13, 52));
var myLatLng = new google.maps.LatLng(npo[1], npo[2]);
var contentString = '<a href="'+npo[4]+'" style="float:left;display:inline-block;padding-right:5px;">'+npo[5]+'</a>'+'<a href="'+npo[4]+'" style="float:left;display:inline-block;width:155px;">'+npo[0]+'</a>'
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
// shadow: shadow,
icon: image,
shape: shape,
title: npo[0],
zIndex: npo[3]
});
attachMessage(marker, contentString);
myLat[i+2] = myLatLng;//実際にはマーカーは2から始まるので、2足す。
}
}
</script>
と、いった感じなのですが、恐らくこれを見てもわかりづらいと思うので、抜粋して説明します。
※全体にちらほら使われているnpoという単語は今回このコードを使用したサイトがNPOさんのサイトだったのでそういう変数名になってますが、全て任意の適当な名前で大丈夫です。
34~55行
$argsにquery_postsのパラメータを設定し、記事一覧を取得しています。今回は特定のカスタム投稿タイプに紐付けてマップにプロットしたかったので、post_typeとか指定しています。今回は細かいWP的な解説は割愛しますね。
取得した記事一覧を元にマップにプロットするマーカーの設定一覧の配列を設定してます。
ここは、基本的には以下のような書式が必要です。
var markers = [
[‘マーカー名’,’緯度’,’経度’,’表示順’],
[‘マーカー名’,’緯度’,’経度’,’表示順’],
[‘マーカー名’,’緯度’,’経度’,’表示順’]
];
それぞれの値に対応するように記事のそれぞれの項目を代入するよう記述します。緯度経度に関しては、カスタムフィールド自体に「xx.xxxx,xx.xxxx」という書式で格納されているので「’緯度’,’経度’」に対して$latという変数ひとつで済ませてます。
その他なにかマーカー個別に使いたい値があれば、配列の要素として追加しておけば、後ほど呼び出すことができます。
ここで定義した1次元の配列の要素数に応じてマーカーがプロットされます。
71行~
マーカー画像を設定する箇所です。
今回は記事ごとに違うマーカーを作成して配置したので、それぞれのファイル名をここで代入しています。今回そのファイル名は、markersで指定した配列の要素としてあらかじめ定義しておきました。
78行
座標に配列で指定した2番目と3番目の値をそれぞれ代入します。
79行
クリックしたときに吹き出しに出る内容を定義します。
80行~
実際にマーカーを配置する処理です。
attachMessage()としてここを関数化したのは、ここに直接吹き出しの値を書くとなんだか上書きされちゃうんです。js詳しい人ならさらっと理解できるようなんですが、僕は当初よく理解できず、他にもひっかかる方がいるかなーと思って一応取り上げました。
90行目
これは後述しますが、マーカーの通番と、query_postsで取得してきた値とがいくつかずれていたのでここで補正をかけています。ここはあまり気にしないでください。
以上でGoogleMap設置に関する処理は完了のはず、です。
さて、さらにもうひと手間かけてみたのですが、マップ外のテキストリンクから、配置したマーカーをマップ中央に持ってくる処理、を付け加えてみました。
//指定した緯度経度にマップを移動させる関数
function toMarker(num) {
myMap.panTo(myLat[num]);
}
最初に書いたコードの↑この部分がそれにあたります。マーカーの座標をあらかじめmyLatに格納しておき、クリックでその座標へとマップを移動させる関数です。
テキストリンクはこんな感じ
<a href="#" onClick="toMarker(<?php echo $user_id; ?>); return false;">map</a>
このnumをきちんと指定してやる必要があるのですが、今回はuser_idと関連づけており、配列の格納順と同期するようテンプレート側のphpでうまいことループを回しています。
これで一応完了です。無事動いています。まだ未公開のクライアントワークなのでサンプルはまだ見せられないのですが・・・
どなたかの参考になれば幸いですし、忘れたころの未来の自分にも参考になりますように。
よいお年をw