WordPress に Google Map を表示する勉強をしてまして
一つの地図に複数のマーカーを表示した時に、同座標が有る場合の対処法に苦戦しました。
以前に記事にした
→ 【自動変換】【プラグイン】 カスタムフィールドの住所 → カスタムフィールドの緯度、経度
で、各記事に入力されている
カスタムフィールドの住所からカスタムフィールドの緯度、経度の値を自動入力して
それを使って複数のマーカーを表示する事は出来るようになりました。
そしてそして、ここからが今回の本題。
当たり前体操ですが
住所が同じ → 全く同じ緯度と経度が入力
されてしまう訳ですね。
そーすると、例えば同じビルに入ってるお店を地図に表示したいのに、2つ目以降のお店は重なってしまって見えない!という事になってしまいました。
その場合には「クリックでマーカーのウィンドウを開いた時に、2つ(またはそれ以上)のお店を一緒に表示する」というパターンも考えられるのですが、それはそれで私の知識では難しく、さらに言い訳させてもらうと、1か所に10のお店があった場合は?とか考えてしまい、この案は上手い具合に却下。
別な方法として「もし同じ座標があった場合には違和感の無い程度に少しズラして表示する」という事を考えました。
それが下記コードです。
【前提条件】として
- 各投稿記事にカスタムフィールドで 緯度→shop_lat 経度→shop_lng を入力
- カテゴリーページで、そのカテゴリーに属している記事に記された緯度と経度を使って複数マーカーを表示
- まず、カスタムフィールドから緯度と経度の値を取得
- その緯度と経度(以下、座標)と同じものが以前に出力されているか?チェック用の配列 check_latlng でチェック
- 出ていれば座標をランダムな値で少しズラし、ズラした後の値を取得
- ズラし後の値はチェック用の配列 check_latlng に格納
という感じになってます。
あと、基本的な事ですが header.php に下記コードが入ってないとウンともスンともなりませんのでご注意を。
1 |
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> |
では、↓ ここからがコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
<?php if(0) { ?> ▼▼▼カテゴリーマップ表示 <?php } ?> <?php if(0) { ?> ▼ カテゴリーIDを取得 <?php } ?> <?php $cat = get_queried_object(); $cat_id = $cat->cat_ID; ?> <?php if(0) { ?> ▲ カテゴリーIDを取得 <?php } ?> <div id="map" style="width: 100%; height: 400px;"></div> <script type="text/javascript"> <?php if(0) { ?> ▼▼ループで各投稿からタイトル、アイキャッチ、緯度、経度(lat_adjust lng_adjustで調整)を取得 <?php } ?> <?php if(0) { ?> ▼ 表示するカテゴリーと記事数を指定 <?php } ?> <?php $args = array( 'cat' => $cat_id, 'posts_per_page' => 999, ); ?> <?php if(0) { ?> ▲ 表示するカテゴリーと記事数を指定 <?php } ?> <?php $check_latlng = array(); ?> <?php if(0) { ?> ▼ここからループ <?php } ?> var locations = [ <?php $loop_query = new WP_Query( $args ); ?> <?php while ( $loop_query->have_posts() ) : $loop_query->the_post(); ?> <?php if(0) { ?> ▼緯度、経度が共に入力されていればループ継続 <?php } ?> <?php if ( post_custom('shop_lat')&&post_custom('shop_lng') ) : ?> <?php if(0) { ?> ▼座標が同じ場合の微調整(少しズラす) <?php } ?> <?php $shop_ido = get_post_custom_values("shop_lat"); $shop_keido = get_post_custom_values("shop_lng"); $shop_idokeido = $shop_ido[0].$shop_keido[0] ; if (in_array($shop_idokeido,$check_latlng)==TRUE) { $lat_adjust = (mt_rand(30,45) / 1000000); $lat_rand = (mt_rand(1,2)); if($lat_rand == 1) {$lat_adjust=$lat_adjust*-1;} $lng_adjust = (mt_rand(30,45) / 1000000); $lng_rand = (mt_rand(1,2)); if($lng_rand == 1) {$lng_adjust=$lng_adjust*-1;} $shop_ido[0] = $shop_ido[0] + $lat_adjust; $shop_keido[0] = $shop_keido[0] + $lng_adjust; $shop_idokeido = $shop_ido[0].$shop_keido[0] ; } $check_latlng[] = $shop_idokeido; ?> <?php if(0) { ?> ▲座標が同じ場合の微調整(少しズラす) <?php } ?> ['<div style="width: 180px; height: 120px;"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><br /><br /><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(array(60,60) ); ?></a></div>', <?php echo $shop_ido[0]; ?>, <?php echo $shop_keido[0]; ?>], <?php endif; ?> <?php if(0) { ?> ▲ここまで 緯度、経度が共に入力されていればループ <?php } ?> <?php endwhile; // end of the loop. ?> <?php wp_reset_postdata(); ?> <?php if(0) { ?> ▲ここまでループ <?php } ?> ]; <?php if(0) { ?> ▲▲ループで各投稿からタイトル、アイキャッチ、緯度、経度(lat_adjust lng_adjustで調整)を取得 <?php } ?> var map = new google.maps.Map(document.getElementById('map')); var infowindow = new google.maps.InfoWindow(); // 表示領域を生成 var bounds = new google.maps.LatLngBounds(); var marker; for (var i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ icon: 'http://maps.google.co.jp/mapfiles/ms/icons/red-dot.png', position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map }); // 地図表示領域をマーカー位置に合わせて拡大 bounds.extend (marker.position); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infowindow.setContent(locations[i][0]); infowindow.open(map, marker); } })(marker, i)); } // 地図表示領域の変更を反映 map.fitBounds (bounds); </script> <?php if(0) { ?> ▲▲▲カテゴリーマップ表示 <?php } ?> |
んー、初心者丸出しのコードなので公開するのも恥ずかしいのですが。
どーいった事をしてるのかと言うと
という作業を繰り返してます。
「わかんねー」とか「表示されないんですけど!」という人はコメント頂ければ、時間のある時にお返事します。
また、「そんな方法じゃなくて、もっと上手な方法はねぇー」と教えてくれる方も絶賛募集中です!