Googleマップで観光スポットを表示しているときに、近くの観光スポットをリストで表示していて、そのスポットをマウスでポイントしてやれば、そのスポットのマーカーを地図に追加して表示し、さらに現在地と追加地のマーカーが全て表示されるようにマップの拡大率を自動的に変更する・・・という仕様が必要になったので、備忘録メモ。
例えば、以下のような地図を表示するようにGoogle Map V3でコードを書きます。
イベント処理をクロスブラウザで考えるのは面倒なので、定番のjQueryで書きますが・・・
<script> $(function(){ var latlng, myOptions, map, markerObj; var now_lat = 34.0522342; var now_lng = -118.2436849; latlng = new google.maps.LatLng(now_lat, now_lng); myOptions = { zoom: 10, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControl: true, navigationControl: true, scaleControl: true }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); markerObj = new google.maps.Marker({position:latlng, map:map, draggable:false}); }); </script>
これで地図が表示されます。
ここでページ上に、「近くにこんなところもありますよ♪」みたいな感じでサウスバレーというスポットが表示されていました。
その文字(写真でも)をポイントすると、地図上にサウスバレーの位置を追加したいと言うことです。
そこで、そのサウスバレーを表示しているHTMLは、
<p class="add-point" data-lat="34.1767667" data-lng="-118.55535509999999"> <a href="http://southvalley.com/">サウスバレー</a> </p>
こんな感じで表示しておきます。
ポイントは、クラス「add-point」を付与していることと、data属性のそれぞれlatとlngに緯度、経度を指定しています。
jQueryを使えばポイントした時というのは簡単にかけますね。
// クラス「add-point」にマウスが重なったら・・・ $('.add-point').hover(function(){ //以下に処理を書く });
あとは、その中にマーカーを追加する処理を書くだけです。
// 追加したマーカー削除 if(spot_marker) spot_marker.setMap(null);
まず、既にマーカーが追加されていれば、それを削除します。
そうでないと、同じ場所をポイントする度に、マーカーが何個も重なって表示されます。
同じ場所に描画されるので、気づきにくいんです。
// スポットの緯度・経度を取得 var spot_lat = $(this).data('lat'); var spot_lng = $(this).data('lng'); var spot_latlng = new google.maps.LatLng(spot_lat, spot_lng);
そして、ポイントした要素のdata属性から緯度と経度を取得して、それをGoogleマップで使えるようにします。
// マーカー表示 spot_marker = new google.maps.Marker({position:spot_latlng, map:map});
マーカーを表示すれば、これでOK・・・ってわけでもないんです。
現在表示されている拡大率で、表示範囲外にマーカーが描画されても気づかないですよね。
なので、元のマーカーと、追加されたマーカーが2つ表示できる最適な拡大率に自動設定してやります。
GoogleマップではfitBoundsメソッドが用意されているので、これを使います。
// マーカーの位置によって地図をフィットさせる if(now_lat > spot_lat){ var max_y = now_lat; var min_y = spot_lat; }else{ var max_y = spot_lat; var min_y = now_lat; } if(now_lng > spot_lng){ var max_x = now_lng; var min_x = spot_lng; }else{ var max_x = spot_lng; var min_x = now_lng; } var southWest = new google.maps.LatLng(max_y, min_x); var northEast = new google.maps.LatLng(min_y, max_x); map.fitBounds(new google.maps.LatLngBounds(southWest, northEast));
2地点の緯度・経度値から、地図の南西の座標と北東の座標から、表示領域を決定します。
これを1つに纏めたのが以下です。
<script> $(function(){ // 地図の描画 var latlng, myOptions, map, markerObj, spot_marker; var now_lat = 34.0522342; var now_lng = -118.2436849; latlng = new google.maps.LatLng(now_lat, now_lng); myOptions = { zoom: 10, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControl: true, navigationControl: true, scaleControl: true }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); markerObj = new google.maps.Marker({position:latlng, map:map, draggable:false}); // ポイントしたら、以下を実行 $('.add-point').hover(function(){ // 追加したマーカー削除 if(spot_marker) spot_marker.setMap(null); // スポットの緯度・経度を取得 var spot_lat = $(this).data('lat'); var spot_lng = $(this).data('lng'); var spot_latlng = new google.maps.LatLng(spot_lat, spot_lng); // マーカー表示 spot_marker = new google.maps.Marker({position:spot_latlng, map:map}); // マーカーの位置によって地図をフィットさせる if(now_lat > spot_lat){ var max_y = now_lat; var min_y = spot_lat; }else{ var max_y = spot_lat; var min_y = now_lat; } if(now_lng > spot_lng){ var max_x = now_lng; var min_x = spot_lng; }else{ var max_x = spot_lng; var min_x = now_lng; } var southWest = new google.maps.LatLng(max_y, min_x); var northEast = new google.maps.LatLng(min_y, max_x); map.fitBounds(new google.maps.LatLngBounds(southWest, northEast)); }); }); </script>
これでサウスバレーをポイントすると、以下のように地図が表示されます。
図の例だとピンを押しピンに変更していますが、上記のコードでは同じマークが表示されます。