2010-07-15 62 views
6

我創建了一個相當複雜的商店定位器。用戶輸入他們的郵編,一張表格返回地圖上帶有相應標記的結果。他們可以翻頁瀏覽結果,標記進一步向外移動,並且fitbounds()功能非常適用於縮小到合適的縮放級別以適應標記。問題是如果你回到更近的位置,fitbounds()沒有放大。即使你輸入一個新的搜索,它也不會放大這些新標記的周圍 - 它將它們放在它們的中心,但保持在它是在之前。我希望這是有道理的。如果有人知道我需要添加什麼才能讓它縮小更近的結果,請幫助。這些是我在標記推送功能結束時調用的谷歌功能:Google Maps API V3 fitbounds()縮小,但從來沒有在

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

謝謝!

回答

0
map.setZoom(10); 

我相信可以接受的範圍是1-20。根據我的經驗,只有整數,小數點打破了地圖。

4

沒錯,fitBounds只有確保提供的邊界是可見的。它不會放大到適當的級別。

您可以先致電setZoom(20),然後fitBounds。

3

嗯,有趣..我使用PHP循環所有(需)標記座標並計算出southWest和northEast的值;原始座標是兩者之間的一半。如果所有標記座標彼此非常接近,fitBounds設置的縮放係數比創建地圖時使用的縮放係數要高得多(放大)。這就是爲什麼我們添加了最後一排..

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); 
    }); 

所以,無論是谷歌已經重新編程的功能,因爲您發佈的問題或..我需要你的代碼的更多信息。

0
fitBounds: function(bounds, mapId) 
    { 
     //bounds: bounds, id: map id 
     if (bounds==null) return false; 
     maps[mapId].fitBounds(bounds); 
    }, 

這應該有所幫助,我使用這種方法和工作正常,在地圖V2有點不同的方式。

7

這裏不需要任何花哨。首先適合邊界然後平移。這會給你適當的縮放幷包含整個邊界。

map.fitBounds(bounds); 
map.panToBounds(bounds); 
+1

這似乎工作。我不知道'panToBounds'沒有'fitBounds'應該做什麼。 – dbkaplun 2012-08-12 04:13:24

9

問題是這樣的:我們設置

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

,使我們可以在以後符合我們的標記在地圖上的邊界區域。 GMaps將總是以相應的方式異步縮小到fitBounds(),但不會放大以達到相同效果(如前面提到的@broady)。這對於許多應用程序來說並不理想,因爲一旦您在地圖上顯示了一系列導致地圖縮小的標記(可能是< 10),它將不會在用戶手動執行縮放時放大。

GMaps將繼續使用(最好沒有更好的單詞)邊界的最縮小的標記收集狀態(對不起)。在每次調用新標記之前將其設置爲「空」,可爲您提供一張全新的地圖。

要自動放大,只需設置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 
} 
+0

謝謝John Smith!您的建議是我能夠在刪除標記後讓我縮小的唯一方法。我感謝您的文章中的細節。 – gorelog 2012-08-15 22:36:41

+0

謝謝你......你救了我的一天:-) – Legionar 2015-04-15 11:00:24

1

事實證明,當你調用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); 
1

我還在使用新標記在同一地圖上再次調用fitBounds時出現地圖縮放問題。這是爲我工作的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); 
} 
+0

謝謝,得到它從你實施作爲角度服務工作:https://gist.github.com/zmijevik/047c40f4fc0bea27fd7c – 2016-03-08 19:53:49

0

我今天遇到這個一般問題,以爲我會分享一個解決方案。我意識到這與你的「商店定位器」問題稍有不同,但它確實適用於許多方面。在我的情況下,我在地圖上收集了一些標記,並且正在添加一個標記,並且希望確保所有標記都處於可見狀態。此代碼檢查每個現有的標記,看看它是否在視圖中,並沿途創建一個新的包圍它們的邊界框(如果需要的話)。最後,如果發現任何內容不在視圖中,視圖將被重置,因此它們都是。

(這使用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); 
} 

人們可以很容易地修改這既保證了新的標記是視圖,通過不循環,只是做一個包含()檢查新標記。