views:

1419

answers:

11

I have a set of points I want to plot on an embedded Google Map (API v3). I'd like the bounds to accommodate all points unless the zoom level is too low (i.e., zoomed out too much). My approach has been like this:

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

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

This doesn't work. The last line "gmap.setZoom()" doesn't change the zoom level of the map if called directly after fitBounds.

Is there a way to get the zoom level of a bounds without applying it to the map? Other ideas to solve this?

+1  A: 

I use:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

This will use the smaller of 24 and the necessary zoom level according to your code, however it probably changes the zoom anyway and doesn't care about how much you zoomed out.

ytg
A: 

I have the exact same problem. Can't get map to fit the bounds as I was able to do with version 2 of the Gmaps API using the map.getBoundsZoomLevel function. Any solution?

korto
this should be a comment, not a answer.. ;)
Tom Brito
true, just because you don't have enough reputation doesn't mean you should use it as an answer :D
cheesebunz
A: 

Hi,

Please try this.

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

If this will helpful to you.

All the best

Kanak Vaghela
A: 

In this function, you need to dynamically add metadata to store the geometry type only because the function accepts any geometry.

"fitGeometries" is a JSON function extending a map object.

"geometries" is an generic javascript array not an MVCArray().

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},
CrazyEnigma
Alternately, I did all the work without knowing that there is an extend() method on the LatLngBounds object. This would be much easier.
CrazyEnigma
+1  A: 

I solved a similar problem in one of my apps. I was a little confused by your description of the problem, but I think you have the same goal I had...

In my app I wanted to plot a one or more markers and ensure the map was showing them all. The problem was, if I relied solely on the fitBounds method, then the zoom-level would be maxed out when there was a single point - that was no good.

The solution was to use fitBounds when there was many points, and setCenter+setZoom when there was only one point.

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

Hope this helps.

Jim Garvin
Your answer have solve my problem with Google Maps V3. Thanks!
FR6
A: 

I don't like to suggest it, but if you must try - first call

gmap.fitBounds(bounds);

Then create a new Thread/AsyncTask, have it sleep for 20-50ms or so and then call

gmap.setZoom( Math.max(6, gmap.getZoom()) );

from the UI thread (use a handler or the onPostExecute method for AsyncTask).

I don't know if it works, just a suggestion. Other than that you'd have to somehow calculate the zoom level from your points yourself, check if it's too low, correct it and then just call gmap.setZoom(correctedZoom)

Joseph Earl
A: 

After calculation of the boundries you can check the distance between upper left and down right corner; then you can understand the zoom level by testing the distance (if distance is too far zoom level would be low) then you can select wheter using setbound method or setZoom..

Orhun Alp Oral
A: 

I use this to ensure the zoom level does not exceed a set level so that I know satellite images will be available.

Add a listener to the zoom_changed event. This has the added benefit of controlling the zoom control on the UI also.

Only execute setZoom if you need to, so an if statement is preferable to Math.max or to Math.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

To prevent zooming out too far:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);
Mantis
+2  A: 

If I'm not mistaken, I'm assuming you want all your points to be visible on the map with the highest possible zoom level. I accomplished this by initializing the zoom level of the map to 16(not sure if it's the highest possible zoom level on V3).

var map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 16
                                        , center: marker_point
                                        , mapTypeId: google.maps.MapTypeId.ROADMAP
});

Then after that I did the bounds stuff:

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

//you can have a loop here of all you marker points
//begin loop
bounds.extend(marker_point);
//end loop

map.fitBounds(bounds);

Result: Success!

koderoid
+1  A: 

All I did is:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

And it works on V3 API.

Petr Svoboda
map.setCenter accepts only one attribute, latlng, and map has no function like getBoundsZoomLevel
Viktor
+1  A: 

Got it! Try this:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { if (map.getZoom() > 16) map.setZoom(16); google.maps.event.removeListener(listener); });

Modify to your needs.

LGT