Google maps API 3 scales to fitBounds

I ran into a problem when calling map.fitBounds seems to zoom out. I am trying to use a backbone.js router to save map borders in a url. I want to be able to bookmark the URL, and then the map looks exactly the same.

I noticed that calling map.fitBounds(map.getBounds()) in the console will always decrease. Where would I like him not to change the map.

Is this normal behavior? How can this be done to make the map look the same from one step to another?

thanks

+8
source share
6 answers

This issue of the Google Maps API has been discussed several times. Cm:

The map.fitBounds() function determines that the viewport contains borders. But the map.getBounds() function returns the bounds of the viewport with some additional field (note that this is normal behavior and no error). Extended borders are no longer suitable in the previous view, so the map is scaled.

A simple solution to your problem is to use the center of the map and zoom level. See map.getCenter() , map.setCenter() , map.getZoom() and map.setZoom() .

+12
source

Fixing this issue in 2017

Compressing the bounding box a little before sending to map.fitBounds() .

Here the function compresses the bounding box:

 // Values between 0.08 and 0.28 seem to work // Any lower and the map will zoom out too much // Any higher and it will zoom in too much var BOUNDS_SHRINK_PERCENTAGE = 0.08; // 8% /** * @param {google.maps.LatLngLiteral} southwest * @param {google.maps.LatLngLiteral} northeast * @return {Array[google.maps.LatLngLiteral]} */ function slightlySmallerBounds(southwest, northeast) { function adjustmentAmount(value1, value2) { return Math.abs(value1 - value2) * BOUNDS_SHRINK_PERCENTAGE; } var latAdjustment = adjustmentAmount(northeast.lat, southwest.lat); var lngAdjustment = adjustmentAmount(northeast.lng, southwest.lng); return [ {lat: southwest.lat + latAdjustment, lng: southwest.lng + lngAdjustment}, {lat: northeast.lat - latAdjustment, lng: northeast.lng - lngAdjustment} ] } 

Use it as follows:

 // Ensure `southwest` and `northwest` are objects in google.maps.LatLngLiteral form: // southwest == {lat: 32.79712, lng: -117.13931} // northwest == {lat: 32.85020, lng: -117.09356} var shrunkBounds = slightlySmallerBounds(southwest, northeast); var newSouthwest = shrunkBounds[0]; var newNortheast = shrunkBounds[1]; // `map` is a `google.maps.Map` map.fitBounds( new google.maps.LatLngBounds(newSouthwest, newNortheast) ); 

I have an application that does the same thing as codr : storing the current map borders in a URL and initializing the map from the URL borders when updating. This solution works great for this.

Why does it work?

Google Maps does this when fitBounds() is fitBounds() :

  • Center the map at the center point of this bounding box.
  • Zoom to the highest zoom level, where the viewport will contain the specified borders inside the viewport field.

If the above estimates exactly coincide with the viewport, Google Maps does not consider this as โ€œcontainingโ€ borders, so it scales another level.

+4
source

For people who see this question in 2018, the Google Maps v3 API now supports the second padding argument, which determines the number of paddings to include around the borders that you specify.

To avoid scaling, just call fitBounds indented with 0 . For this example, it will be map.fitBounds(map.getBounds(), 0)

+3
source

I also noticed this problem. My solution is to compare map.getBounds() with what I am setting the borders for; if they match, I skip the map.fitBounds() call.

0
source

I ran into the same problem and @Tomik's answer helped me solve it. Here are snippets of code that I used.

Save previous zoom and center.

 const lastMapZoom = this.map.getZoom(); const lastMapCenter = this.map.getCenter(); 

To set the values โ€‹โ€‹back.

 this.map.setCenter(lastMapZoom); this.map.setZoom(lastMapCenter); 
0
source

I noticed this behavior when using fitBounds() in a hidden map view (using fitBounds() a rendering interface such as Angular). Since this was a mobile view, I first showed a list of locations and filled in markers on a hidden map while the list was loading (simultaneous loading). Therefore, when the user wants to view the map and switch the segment view / tab / whatever, the map will be displayed with already loaded and visible markers. But it distorted and scaled up to show the whole world on a map.

 <div [hidden]="view !== 'map'> <google-map></google-map> </div> 

fitBounds() needs to load the map in the view, since it uses map sizes to resize the map. If the map is hidden, it zooms in on the map until a full map is displayed.

The solution was simple: when switching the view, call fitBounds() again.

 <button (click)="showMap()">Show Map</button> public showMap() { this.view = 'map'; setTimeout(() => { if (typeof this.map !== 'undefined') this.map.fitBounds(this.bounds); }); } 

Note. I wrapped setTimeout around fitBounds() so that Angular can complete the life cycle and display the map before it is called.

0
source

All Articles