2012-03-23 10 views
18

w mapach Google API v2 mapa naszego kraju był ładnie dopasowany do 700x400px mapie z następujących czynności:Jak wpływać na margines „Grace” z map.fitBounds()

map.getBoundsZoomLevel(<bounds of our country>) 

Ale API v3, map.fitBounds() metoda nie mieści się na tym poziomie powiększenia do 700x400 - powoduje pomniejszenie o jeden poziom.

Oznacza to, że map.fitBounds() liczy się z pewnym "marginesem łaski" lub czymś.

Jak mogę wpłynąć na wielkość tego marginesu?

+0

Czy "margines łaski" może być procentem żądanych granic? Jeśli ten margines jest ustalony, możesz wprowadzić jeszcze mniejsze, zmierzone granice, aby dopasowaćBounds(), tak aby koniec marginesu łaski pasował do twoich początkowo pożądanych granic. Mam nadzieję, że to ma sens. –

+0

@HeitorChang, byłoby to naprawdę hacky i niezdarne rozwiązanie, ale i tak nie wiedząc, jak dokładnie "marginesu łaski" jest obliczany przez fitBounds(), nie można tego zrobić. – TMS

+7

Po hackowaniu doszedłem do wniosku, że funkcja v3 fitBounds() będzie powiększać tylko wtedy, gdy na długim poziomie na tym poziomie powiększenia znajdzie się co najmniej 45-pikselowe wypełnienie (na obu bokach prostokąta zdefiniowane za pomocą twoich granic). Przypuśćmy, że jest to bliska rozmowa, mapa pozostanie pomniejszona, pozostawiając duży margines. Mam nadzieję, że może ci się przydać. –

Odpowiedz

2

Oto rozwiązanie, które pozwala maksymalnie przybliżyć mapę bez marginesu własnego. Powinieneś być w stanie dostosować go do rachunku za pewien margines, jeśli chcesz.

Moje rozwiązanie oparte jest na numerze this comment in a Google Groups thread. Niestety, wywołanie helper.getProjection() zawsze zwracało wartość undefined, więc nieco dostosowałem powyższą odpowiedź i wymyśliłem ten działający kod.

Wystarczy zastąpić istniejące połączenia do map.fitBounds(bounds) z myFitBounds(map, bounds):

function myFitBounds(myMap, bounds) { 
    myMap.fitBounds(bounds); 

    var overlayHelper = new google.maps.OverlayView(); 
    overlayHelper.draw = function() { 
     if (!this.ready) { 
      var projection = this.getProjection(), 
       zoom = getExtraZoom(projection, bounds, myMap.getBounds()); 
      if (zoom > 0) { 
       myMap.setZoom(myMap.getZoom() + zoom); 
      } 
      this.ready = true; 
      google.maps.event.trigger(this, 'ready'); 
     } 
    }; 
    overlayHelper.setMap(myMap); 
} 

// LatLngBounds b1, b2 -> zoom increment 
function getExtraZoom(projection, expectedBounds, actualBounds) { 
    var expectedSize = getSizeInPixels(projection, expectedBounds), 
     actualSize = getSizeInPixels(projection, actualBounds); 

    if (Math.floor(expectedSize.x) == 0 || Math.floor(expectedSize.y) == 0) { 
     return 0; 
    } 

    var qx = actualSize.x/expectedSize.x; 
    var qy = actualSize.y/expectedSize.y; 
    var min = Math.min(qx, qy); 

    if (min < 1) { 
     return 0; 
    } 

    return Math.floor(Math.log(min)/Math.log(2) /* = log2(min) */); 
} 

// LatLngBounds bnds -> height and width as a Point 
function getSizeInPixels(projection, bounds) { 
    var sw = projection.fromLatLngToContainerPixel(bounds.getSouthWest()); 
    var ne = projection.fromLatLngToContainerPixel(bounds.getNorthEast()); 
    return new google.maps.Point(Math.abs(sw.y - ne.y), Math.abs(sw.x - ne.x)); 
} 
+0

To zadziałało dobrze, ale musiałem zmodyfikować jedną linię, aby poradzić sobie z błędem zaokrąglania zmiennoprzecinkowego, gdy "expectedSize" jest dokładnie dwukrotnie "actualSize". Zmieniono wyrażenie return 'getSizeInPixels' na: ' return new google.maps.Point ( Math.round (10000 * Math.abs (sw.y - ne.y))/10000, Math.round (10000 * Math.abs (sw.x - ne.x))/10000 ); ' –

0

Teraz, fitBounds metoda ma drugi parametr, który reprezentuje rozmiar wypełniania. Dla tych, którzy chcą go usunąć, wystarczy podać 0.

Map.map.fitBounds(bounds, 0); 


New method signature: fitBounds(bounds:LatLngBounds|LatLngBoundsLiteral, padding?:number) 
Powiązane problemy