10

ある種の非常に複雑な店舗ロケーターを作成しました。ユーザーが郵便番号を入力すると、テーブルに結果が返され、対応するマーカーが地図上に表示されます。結果のページをめくることができ、マーカーはどんどん外側に移動します。このfitbounds()機能は、マーカーに合わせて適切なズーム レベルにズームアウトするのに最適です。問題は、より近い場所にページを戻してfitbounds()もズームインしないことです。新しい検索を入力しても、それらの新しいマーカーの周りでズームインしません。マーカーはそれらを中心にしていますが、ズーム レベルに関係なくそのままです。以前。これが理にかなっていることを願っています。より近い結果にズームインするために何を追加する必要があるかを誰かが知っている場合は、助けてください。これらは、マーカープッシュ関数の最後に呼び出す Google 関数です。

  map.setCenter(bounds.getCenter());
  map.panToBounds(bounds);
  map.fitBounds(bounds);

ありがとう!

4

12 に答える 12

11

ここには特別なものは必要ありません。最初に境界に合わせてから、それにパンします。これにより、適切なズームが得られ、境界全体が含まれます。

map.fitBounds(bounds);
map.panToBounds(bounds);
于 2011-09-06T22:29:52.873 に答える
10

問題はこれです:私たちは設定しました

var bounds = new google.maps.LatLngBounds();

後でマップ上の境界領域にマーカーを合わせることができるようにします。GMaps は常に fitBounds() に応じて非同期的にズームアウトしますが、同じことを達成するためにズームインすることはありません (以前に @broady によって指摘されたように)。これは、多くのアプリケーションにとって理想的ではありません。一度マップをズームアウトする原因となった一連のマーカーをマップ上に表示すると (おそらく 10 未満)、ユーザーが手動でズームインしないと元に戻りません。

GMaps は、(より適切な言葉がない) 最もズームアウトされたマーカー コレクション ステータスの境界を引き続き使用します (申し訳ありません)。新しいマーカーの各呼び出しの前に「null」に設定すると、操作する新しいマップが得られます。

自動ズームインするには、LatLngBounds(); を設定するだけです。そのように「null」にします(その配置を確認するには、以下の疑似例を参照してください):

bounds = new google.maps.LatLngBounds(null);

疑似例:

// map stuff/initiation
...

var bounds = new google.maps.LatLngBounds();
var gmarkers = [];

function CreateMarker (obj) {
    myLatLng = new google.maps.LatLng(obj['latitude'], obj['longitude']);
    marker = new google.maps.Marker({
        position: myLatLng,
        map: map
    });
    google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
            infowindow.setContent(obj['job']);
            infowindow.open(map, marker);
        }
    })(marker, i));
    bounds.extend(myLatLng);
    gmarkers.push(marker);
}

....

// here's an AJAX method I use to grab marker coords from a database:

$.ajax({
    beforeSend: function() {
        clear_markers(gmarkers); // see below for clear_markers() function declaration
    },
    cache: false,
    data: params,
    dataType: 'json',
    timeout: 0,
    type: 'POST',
    url: '/map/get_markers.php?_=<?php echo md5(session_id() . time() . mt_rand(1,9999)); ?>',
    success: function(data) {
        if (data) {
            if (data['count'] > 0) {
                var obj;
                var results = data['results'];

                // Plot the markers
                for (r in results) {
                    if (r < (data['count'])) {
                        CreateMarker(results[r]);
                    }
                }
            }
        }
    },
    complete: function() {
        map.fitBounds(bounds);
    }
});

// clear_markers()
function clear_markers(a) {
    if (a) {
        for (i in a) {
            a[i].setMap(null);
        }
        a.length = 0;
    }
    bounds = new google.maps.LatLngBounds(null); // this is where the magic happens; setting LatLngBounds to null resets the current bounds and allows the new call for zoom in/out to be made directly against the latest markers to be plotted on the map
}
于 2012-04-24T16:13:18.503 に答える
7

そうです、指定された境界が表示されることfitBoundsのみを保証します。適切なレベルにズームインしません。

最初に を呼び出しsetZoom(20)、次に fitBounds を呼び出すことができます。

于 2010-10-11T16:05:59.570 に答える
4

うーん、興味深い.. PHP を使用して、すべての (あるべき) マーカー座標をループし、southWest と northEast の値を計算します。原点座標は 2 つの中間です。すべてのマーカー座標が互いに非常に近い場合、fitBounds によって設定されたズーム係数は、マップ作成時に使用された 15 よりもはるかに大きくなります (拡大されます)。そのため、最後の行を追加しました..

var map;

function mapInit() {
  var origin = new google.maps.LatLng(59.33344615, 18.0678188);
  var options = {
    zoom: 15,
    center: origin,
    mapTypeControlOptions: {
      mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID]
    },
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById("googlemap"), options);

  var southWest = new google.maps.LatLng(59.3308415, 18.0643054);
  var northEast = new google.maps.LatLng(59.3360508, 18.0713322);
  var bounds = new google.maps.LatLngBounds(southWest, northEast);
  map.fitBounds(bounds);

  google.maps.event.addListenerOnce(map, "idle", function() {
    if (map.getZoom() > 16) map.setZoom(16);
  });

したがって、質問を投稿してからGoogleが関数を再プログラムしたか、コードに関する詳細情報が必要です。

于 2010-11-04T03:04:32.393 に答える
3

また、新しいマーカーを使用して同じマップで fitBounds を 2 回呼び出すと、マップがズームアウトするという問題もありました。これは私のために働くfrankensolutionです:

// This is a stationary point tho dynamic will work too

var myLat = someLat,
    myLng = someLong;

var map = false,
    markersArray = [];

function makeOrderMap(lat, lng) { // pass in dynamic point when updating map

  var mapOptions = {
      center: new google.maps.LatLng(myLat, myLng),
      zoom: 16,
      mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  deleteOverlays(); // remove any existing markers..
  if(!map) {  
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  } 

  // Find the mid-point to center the map

  midLat = (parseFloat(lat) + parseFloat(myLat)) / 2;
  midLng = (parseFloat(lng) + parseFloat(myLng)) / 2;
  map.setCenter(new google.maps.LatLng(midLat, midLng));
  var newSpot = new google.maps.LatLng(lat, lng); 

  placeMarker(mapOptions.center);    
  placeMarker(newSpot);   

  // determine the distance between points for deciding the zoom level

  var dist = distHaversine(mapOptions.center, newSpot);

  var zoom = 10;
  if(dist < 1.25) {
    zoom = 15;
  } else if(dist < 2.5) {
    zoom = 14;
  } else if(dist < 5) {
    zoom = 13;
  } else if(dist < 10) {
    zoom = 12;
  } else if(dist < 20) {
    zoom = 11;
  }
  map.setZoom(zoom);  
}


rad = function(x) {return x*Math.PI/180;}

distHaversine = function(p1, p2) {
  var R = 6371; // earth's mean radius in km
  var dLat  = rad(p2.lat() - p1.lat());
  var dLong = rad(p2.lng() - p1.lng());

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  var d = R * c;

  return d.toFixed(3);
}

function deleteOverlays() {
    if (markersArray) {
        for (i in markersArray) {
            markersArray[i].setMap(null);
        }
    markersArray = [];    
    markersArray.length = 0;
    }    
}

function placeMarker(location, alt_icon) {

    var marker = new google.maps.Marker({
        position: location, 
        map: map
      });

    // add marker in markers array
    markersArray.push(marker);
}
于 2013-10-11T22:47:31.293 に答える
2

呼び出すmap.getBounds()と、端に少し余裕のあるビューポートが返されることがわかります。この新しい境界は現在の境界よりも大きいため、マップは常に縮小されます。現在のマップの境界を完全に使用することを避け、別の LatLngBounds 変数を維持することで解決できました。ポイントを追加するたびに、次のように呼び出しました。

markersBounds.extend(newMarkersLatLng);
map.fitBounds(markersBounds);
map.panToBounds(markersBounds);

ポイントを削除するには (私は常に追加していました)、最初のポイントで新しい LatLngBounds オブジェクトを作成し、残りの各ポイントを拡張して新しい境界を取得できます。

var markersBounds = new google.maps.LatLngBounds(markers[0].getPosition(),
                                                 markers[0].getPosition());
for(var i=1; i<markers.length; i++){
    markersBounds.extend(markers[i].getPosition());
}

map.fitBounds(markersBounds);
map.panToBounds(markersBounds);
于 2013-04-12T15:24:48.883 に答える
1

今日、この一般的な問題に遭遇したので、解決策を共有したいと思いました。これは「店舗検索」の問題とは少し異なりますが、多くの点で当てはまります。私の場合、マップ上にマーカーのコレクションがあり、1 つ追加していて、すべてのマーカーが表示されていることを確認したいと考えています。このコードは、既存の各マーカーをチェックして、ビュー内にあるかどうかを確認し、必要に応じて、それらすべてを含む新しい境界ボックスを作成します。最後に、ビューにないものが見つかった場合、ビューがリセットされ、すべてがビューに表示されます。

(これは Dojo の配列モジュールを使用します。基本的な配列反復の便利なラッパーです)

var origBounds = map.getBounds(),
    newBounds = new google.maps.LatLngBounds(null),
    anyFailed = false;
array.forEach(markers, function (m) {
    newBounds.extend(m.position);
    if (!origBounds.contains(m.position)) {
        anyFailed = true;
    }
});
if (anyFailed) {
    map.setCenter(newBounds.getCenter());
    map.fitBounds(newBounds);
}

これを簡単に変更して、ループせずに新しいマーカーで contains() チェックを実行するだけで、新しいマーカーが確実に表示されるようにすることができます。

于 2014-01-06T01:36:38.593 に答える
0
fitBounds: function(bounds, mapId)
    {
        //bounds: bounds, id: map id
        if (bounds==null) return false;
        maps[mapId].fitBounds(bounds);
    },  

これは役立つはずです。私はこのメソッドを使用し、マップ v2 で少し異なる方法で正常に動作します。

于 2011-03-13T14:48:05.210 に答える
0
map.setZoom(10);

許容範囲は 1 ~ 20 だと思います。私の経験では、整数のみ、小数は地図を壊しました。

于 2010-07-15T04:18:12.610 に答える