Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make fitBounds aware of custom controls

I have a large (300*500px) custom control on the left side of my google map. I'm clustering my markers together. When a user clicks on a marker, I want to zoom the map in to show the markers in that cluster.

The problem is:

When I get the bounds of my marker collection, then map.fitBounds(collection_bounds), I end up with markers underneath my large control. Is there a way to prevent fitBounds from using the whole view port?

I have tried getting the LatLng of my south west bounds point, converting that to pixels, moving that 300px in, then converting that back to a LatLng to use as the new south west bounds point. This doesn't work though because the calculations are done before the zoom, so the 300px shift ends up being too much... I thought about writing my own fitBounds, but I hit the same issue, in that it's done before the zoom.

like image 953
Soup Avatar asked Aug 28 '12 04:08

Soup


2 Answers

What you said works:

I have tried getting the LatLng of my south west bounds point, converting that to pixels, moving that 300px in, then converting that back to a LatLng to use as the new south west bounds point.

if you do it in two steps, which is pretty much transparent to the user because it is executed so fast that you hardly notice it. So, first you do a normal map.fitBounds(bounds); where bounds is only defined by your markers, and then you re-adjust with the technique you described. So:

  google.maps.event.addListenerOnce(map,'bounds_changed',function(){
    // re-adjust bounds here as you described. 
    // This event fires only once and then the handler removes itself.
  });
  map.fitBounds(bounds);
like image 94
Marcelo Avatar answered Oct 11 '22 15:10

Marcelo


I had a 400pixel wide panel on the right hand size.

Starting from a call to zoomWithPoints passing two points to include in view, the following code implements the approach others have described: 1) Zoom to bounds 2) Using the resulting zoom level calculate how much to add onto the 'maxLon' 3) Zoom to bounds again.

function zoomToBbox(minLat, minLon, maxLat, maxLon) {
   var southwest = new google.maps.LatLng(minLat, minLon);
   var northeast = new google.maps.LatLng(maxLat, maxLon);
   var bounds = new google.maps.LatLngBounds(southwest, northeast);
   map.fitBounds(bounds);      
}

function zoomWithPoints(lat1, lon1, lat2, lon2) {
   var maxLat = Math.max(lat1, lat2);
   var maxLon = Math.max(lon1, lon2);
   var minLat = Math.min(lat1, lat2);
   var minLon = Math.min(lon1, lon2);

   zoomToBbox(minLat, minLon, maxLat, maxLon);

   var z = map.getZoom(); //get the zoom level after zooming

   // Add a bit to maxLon, to result in it panning left by 400 pixels
   var widthOfPanel = 400;
   var degreesPerTile = 360 / (Math.pow(2,z));
   var degreesPerPx = degreesPerTile / 256;
   var degreesForPanel = degreesPerPx * widthOfPanel;

   maxLon = maxLon + degreesForPanel;

   //zoom (pan across a bit) to take account of the added bit
   zoomToBbox(minLat, minLon, maxLat, maxLon);

   map.setZoom(z); //put it back to right zoom level if necessary
}

...call zoomWithPoints
like image 34
Harry Wood Avatar answered Oct 11 '22 15:10

Harry Wood