Jonathan Weber
Jonathan Weber

Reputation: 472

Realign Google Maps to fit all markers into to the right 70% of the map

I would like to provide a client with a solution for displaying all of the branches in one city on a map (Google Maps JavaScript API). The map behaves more like an in-website app than a typically Google Map - it is not draggable, zoomable, and so on.

I put together a tiny function that handles repositioning of the map to have all markers in the maps viewport. This function is called on pageload and everytime the window is resized.

While this works perfectly, I need to fine-tune this script even more and this is where I have no clue on how to do it: Later on, there will be an permanent info-window overlaying the left 30% of the map. To prevent markers from being hidden under it, it would be nice if the realign function could be restricted to use only the right 70% of the map object for calculation.

Here is what the funtion currently looks like:

function realignMap() {
  resizeFinished(function(){
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < markers.length; i++) {
      bounds.extend(markers[i].getPosition());
    }
    map.fitBounds(bounds);
  }, 300, 'mapresizeuniqueid');
}

map and markers are global variables containing the Google Maps map-object and an array Google Maps marker-objects. resizeFinished is a small work-around for a bug where maximizing and snapping of the window will prevent the event from being fired.

Thanks in advance for any tipp you can provide! Greetings - Jonathan

P.S.: Please don't provide jQuery solutions if not necessary...

Upvotes: 0

Views: 459

Answers (1)

Matej P.
Matej P.

Reputation: 5383

I can think of two solutions to this problem:

1. shrink the map div to the size you actually want. Why do you even display a div over map? Why don't you just shrink the map div when the info-window is present? And then resize it back when info-window is not present (care: trigger resize event on map after you do any of those operations) If you have no actual reason to do this I suggest you to go with this solution.

2. If 1. is not viable for you can create a fake bounds element, which would be in the appropriate distance ti the left from the calculated bounds. E.g. your original bounding box lng starts at 50 and ends in 70. That means it's width is 20, 20*0.3=6 so you would create a fake element at lng 50-6=44 and fit map into those new bounds. So your code would look something like this (untested):

function realignMap() {
  resizeFinished(function(){
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < markers.length; i++) {
      bounds.extend(markers[i].getPosition());
    }
    var width = bounds.getSouthWest().lng() > bounds.getNorthEast().lng() ? (180 - bounds.getSouthWest().lng()) + (bounds.getNorthEast().lng() - (-180)) : bounds.getSouthWest().lng() - bounds.getNorthEast().lng();
    if(width > 180);
    var new_lng = bounds.getSouthWest().lng() - (width * 0.3);
    if(new_lng < -180) new_lng = 180 - (-180 - new_lng);
    bounds.extend(new google.maps.LatLng(bounds.getCenter().lat(), new_lng);
    map.fitBounds(bounds);
  }, 300, 'mapresizeuniqueid');
}

Of course this wouldn't work if your markers are covering bigger lng span than 70% of whole earth.

EDIT Edited the code to work when bounds.getSouthWest().lng() > bounds.getNorthEast().lng()

Upvotes: 3

Related Questions