GoogleMaps全部のGMarker(マーカー/ピン)が一画面に収まるような縮尺を自動計算する方法
引き続き、、GoogleMaps調査中。。
マーカーを複数立てた時に、全部のマーカーが一画面に収まるような縮尺を自動計算したいものです。
Google Maps APIについてのGoogleGroupにも過去にその議論はあって、
1.各ズームサイズにおける縮尺(というか経度緯度とドットとの関係)の計算の仕方
全国ロケ地図(http://saya.s145.xrea.com/x/lmap.html)を作っているときに、全てのマーカーを表示したいとか、マーカーを重ならないように引き出し線等で表示したい(印刷用)という要望がありました。
前者は、全マーカの中心に移動しズームアウトしていき、表示範囲を取得(getBoundsLatLng)して全て入ったところでやめるというかなり無理矢理な-やり方をしています。
後者も表示範囲(getSpanLatLng)から経度緯度とドットの関係を計算して、うまく配置するしかないのでしょうか?
その議論の中で紹介されていなかった、smartな解法を見つけた(その後GoogleMapsAPIに追加された?)ので御紹介。
Google Maps API Version 2 Referenceを見ると、GLatLngBoundsというクラスがあります。
class GLatLngBounds
A GLatLngBounds instance represents a rectangle in geographical coordinates, including one that crosses the 180 degrees meridian.
そのひとつのmethod、extendが使えます。
extend(latlng)
Enlarges this rectangle such that it contains the given point. In longitude direction, it is enlarged in the smaller of the two possible ways. If both are equal, it is enlarged at the eastern boundary.
さらにGMap2のgetBoundsZoomLevelってmethod。
getBoundsZoomLevel(bounds)
Returns the zoom level at which the given rectangular region fits in the map view. The zoom level is computed for the currently selected map type. If no map type is selected yet, the first on the list of map types is used.
javascriptコードはこんな。
List[0] = self.createMarker( 0, new GLatLng( 35.678084480, 139.76313114 ) );
List[1] = self.createMarker( 1, new GLatLng( 35.66278800541137 , 139.7543442249298 ) );
List[2] = self.createMarker( 2, new GLatLng( 35.67073730876408 , 139.76759433746338 ) );
List[3] = self.createMarker( 3, new GLatLng( 35.65085384825412 , 139.7745680809021 ) );
List[4] = self.createMarker( 4, new GLatLng( 35.668497289125376 , 139.75984811782837 ) );
self.initZoom();
中略
createMarker : function( num, point ) {
var letter = Letter.getNext();
var ic = new GIcon(baseIcon);
ic.image = "img/icons/icon"+letter+".png";
var marker = new GMarker(point, { icon: ic});
map.addOverlay( marker );
return marker;
},
initZoom : function(){
var gb;
var first = 1;
for( var index in List ){
var marker = List[index];
if( first ){
gb = new GLatLngBounds( marker.getPoint(), marker.getPoint() );
first = 0;
}else{
var point = marker.getPoint();
gb.extend( point );
}
}
map.setCenter( gb.getCenter(), map.getBoundsZoomLevel( gb ) );
}
