2012-03-23 7 views
18

In Google Maps API v2, mappa del nostro paese era ben montato alla mappa 700x400px con il seguente:Come influenzare il "margine di grazia" di map.fitBounds()

map.getBoundsZoomLevel(<bounds of our country>) 

Ma in API v3, il Il metodo map.fitBounds() non si adatta a quel livello di zoom a 700x400: ingrandisce un livello.

Ciò significa che map.fitBounds() conta con qualche "margine di tolleranza" o qualcosa del genere.

Come posso influire sulla dimensione di questo margine?

+0

Il "margine di tolleranza" può essere una percentuale dei limiti desiderati? Se questo margine è fisso, puoi inserire un limite ancora più piccolo, misurato, per inserire Bounds(), in modo che la fine del margine di grazia corrisponda ai limiti originariamente desiderati. Spero che abbia senso. –

+0

@HeitorChang, questa sarebbe davvero una soluzione hacky e maldestra, ma comunque senza sapere come esattamente il "grace margin" è calcolato da fitBounds(), non puoi farlo. – TMS

+7

Dopo aver hackerato, ho concluso che v3 fitBounds() eseguirà lo zoom in avanti solo se è presente almeno una sfumatura di 45 pixel (su entrambi i lati del rettangolo definito dai limiti) sulla dimensione lunga, a quel livello di zoom. Supponendo che si tratti di una chiamata ravvicinata, la mappa rimarrà ingrandita, lasciando un grande margine. Spero che questo possa esserti utile. –

risposta

2

Ecco una soluzione che ingrandirà la mappa il più lontano possibile senza margine personalizzato. Dovresti essere in grado di adattarlo per tenere conto di un margine se lo desideri.

La mia soluzione è basata su this comment in a Google Groups thread. Sfortunatamente, la chiamata a helper.getProjection() è sempre tornata indefinita, quindi ho adattato la risposta sopra un po 'e ho trovato questo codice funzionante.

Basta sostituire le chiamate esistenti per map.fitBounds(bounds) con 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

Questo ha funzionato bene per me, ma ho dovuto modificare una riga per gestire un errore di arrotondamento in virgola mobile quando 'expectedSize' è esattamente il doppio' actualSize'. Modificata la dichiarazione di ritorno di 'getSizeInPixels' a: ' 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

Ora, i fitBounds metodo ha un secondo parametro che rappresenta la dimensione dell'imbottitura. Per coloro che vogliono rimuoverlo, è sufficiente passare 0.

Map.map.fitBounds(bounds, 0); 


New method signature: fitBounds(bounds:LatLngBounds|LatLngBoundsLiteral, padding?:number) 
Problemi correlati