2012-03-23 15 views
18

En los mapas de Google API v2, mapa de nuestro país fue muy bien equipados al mapa 700x400px con lo siguiente:Cómo afectará el "margen de tolerancia" de map.fitBounds()

map.getBoundsZoomLevel(<bounds of our country>) 

Pero en versión 3 del API, la El método map.fitBounds() no se ajusta a ese nivel de zoom a 700x400 - aleja un nivel.

Esto significa que map.fitBounds() cuenta con un "margen de gracia" o algo así.

¿Cómo puedo afectar el tamaño de este margen?

+0

¿Podría el "margen de gracia" ser un porcentaje de sus límites deseados? Si este margen es fijo, puede ingresar límites aún más pequeños y medidos a fitBounds(), de modo que el final del margen de gracia coincida con sus límites originalmente deseados. Espero que esto tenga sentido. –

+0

@HeitorChang, esta sería una solución realmente estrafalaria y torpe, pero de todos modos sin saber cómo exactamente el "margen de gracia" es calculado por fitBounds(), no se puede hacer eso. – TMS

+7

Después de piratear, llegué a la conclusión de que v3 fitBounds() solo acercará si hay al menos un relleno de 45 píxeles (a ambos lados del rectángulo definido por sus límites) en la dimensión larga, en ese nivel de zoom. Suponiendo que es una decisión cercana, el mapa se mantendrá alejado, dejando un gran margen. Espero que esto te sea útil. –

Respuesta

2

Aquí hay una solución que ampliará el mapa en la medida de lo posible sin un margen personalizado. Debería poder adaptarlo a la cuenta por un margen si lo desea.

Mi solución se basa en this comment in a Google Groups thread. Lamentablemente, la llamada al helper.getProjection() siempre devolvió indefinido, así que adapté un poco la respuesta anterior y obtuve este código de trabajo.

Basta con sustituir las llamadas existentes a 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

Esto funcionó bien para mí, pero tuve que modificar una línea para hacer frente a un error de redondeo de punto flotante cuando 'expectedSize' es exactamente el doble' actualSize'. Se cambió la declaración de devolución de '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

Ahora, los fitBounds método tiene un segundo parámetro que representa el tamaño de la separación. Para aquellos que quieren eliminarlo, solo necesita pasar 0.

Map.map.fitBounds(bounds, 0); 


New method signature: fitBounds(bounds:LatLngBounds|LatLngBoundsLiteral, padding?:number) 
Cuestiones relacionadas