すばやくアクセスできるように、このソリューションのjsfiddleは次のとおりです。http://jsfiddle.net/nYz6k/
中心に対する境界を検出する現在のソリューションに満足していると仮定すると、現在のマップキャンバスサイズに基づいて境界を制限するだけです。
現在取得している結果は、完全に制限されている場合(つまり、緯度と経度の両方が境界のコーナーを超えている場合)、制限境界のすべてのコーナーがマップの中央に表示されることです。
解決策は、実際に境界からxおよびyオフセットを削除し、それでも中心に対してチェックできるようにすることです(これは、他の境界ベースのチェックソリューションと比較して最も効率的なソリューションです)。
また、マップを初期化するとき、およびウィンドウのサイズを変更するときにのみ境界を制限する必要があります。つまり、パンするときに、すでに提供したチェックメソッド以外に余分な処理オーバーヘッドはありません。
マップのmaxZoomプロパティを設定することを忘れないでください(必要に応じて微調整してください)。これは、決定されたズームレベルを超えると、制限範囲自体がビューポートに収まり、その解決策がないためです。
重要!「drag」の代わりに「center_changed」を使用します。これは、「drag」には、ドラッグを終了して中心を設定したときに、マップがパンの方向にスライドするというスライド動作があるためです。
ソリューションを実装する前に、Maps APIの座標系と投影法がどのように機能するかを確認することをお勧めします。これは、このソリューションがそれに大きく基づいているためです。微調整する場合は、この情報を知っておくと便利です。
https://developers.google.com/maps/documentation/javascript/maptypesをクリックし、[カスタムマップタイプ]->[マップ座標]セクションを確認してください。
これがあなたがする必要があることです。まず、地理座標(LatLng)とピクセル座標を変換する2つの短い方法を実装する必要があります。
var fromLatLngToPixel = function (latLng) {
var point = map.getProjection().fromLatLngToPoint(latLng);
var zoom = map.getZoom();
return new google.maps.Point(
Math.floor(point.x * Math.pow(2, zoom)),
Math.floor(point.y * Math.pow(2, zoom))
);
}
var fromPixelToLatLng = function (pixel) {
var zoom = map.getZoom();
var point = new google.maps.Point(
pixel.x / Math.pow(2, zoom),
pixel.y / Math.pow(2, zoom)
);
return map.getProjection().fromPointToLatLng(point);
}
次に、境界を効果的に制限するメソッドを実装します。マップキャンバスのサイズが変更されるたびに結果の境界が変更されるため、元の境界を格納する変数を常に保持する必要があることに注意してください。
このために、originalBoundsがsw_lat、sw_longなどで指定した境界を保持し、shrinkedBoundsがこのメソッドによって変更されたとします。strictBoundsに名前を変更して、メソッドで引き続き機能させることができますが、それはあなた次第です。これは、jQueryを使用してキャンバスオブジェクトの幅と高さを取得します。
var shrinkBounds = function () {
zoom = map.getZoom();
// The x and y offset will always be half the current map canvas
// width and height respectively
xoffset = $('#map_canvas').width() / 2;
yoffset = $('#map_canvas').height() / 2;
// Convert the bounds extremities to global pixel coordinates
var pixswOriginal = fromLatLngToPixel(originalBounds.getSouthWest());
var pixneOriginal = fromLatLngToPixel(originalBounds.getNorthEast());
// Shrink the original bounds with the x and y offset
var pixswShrinked = new google.maps.Point(pixswOriginal.x + xoffset, pixswOriginal.y - yoffset);
var pixneShrinked = new google.maps.Point(pixneOriginal.x - xoffset, pixneOriginal.y + yoffset);
// Rebuild the shrinkedBounds object with the modified
shrinkedBounds = new google.maps.LatLngBounds(
fromPixelToLatLng(pixswShrinked),
fromPixelToLatLng(pixneShrinked));
}
次に、あなたがしなければならないのはこのメソッドを呼び出すことです:
マップが初期化されるときに1回。メソッドを呼び出すタイミングによっては、マップがすべてのプロパティをまだ初期化していない可能性があるため、奇妙なエラーが発生する可能性があることに注意してください。最善の方法は、projection_changedイベントを使用することです。
google.maps.event.addListener(map, 'projection_changed', function (e) {
shrinkBounds();
});
マップキャンバスのサイズが変更されるたび
google.maps.event.addListener(map, 'resize', function (e) {
shrinkBounds();
});
ただし、これの最も重要な部分は、マップコンテナのプログラムによるサイズ変更に対して「サイズ変更」イベントがトリガーされないことです。したがって、プログラムでキャンバスのサイズを変更するたびに手動でトリガーする必要があります(そうする場合は、そうすることはできません)。 。
最も一般的な方法は、ウィンドウのサイズが変更されたときにトリガーすることです。
$(window).resize(function () {
google.maps.event.trigger(map, 'resize');
});
これで、メソッドを安全に使用できるようになりましたが、前述のように「ドラッグ」ではなく「center_changed」のハンドラーとして使用できます。
完全に機能するコードを使用してjsfiddleをセットアップしました。
http://jsfiddle.net/nYz6k/
境界の南西隅に配置されている小さなハーフマーカーが表示されている左下隅に制限が表示されます。北西の角にも1つありますが、位置の上に表示されているので当然見えません。