Search code examples
javascriptcordovagoogle-maps-api-3

Google Maps API 3 - Show All Markers on Screen, but Keep Centerpoint


This is very similar to this question. I would like to ensure that all markers are shown at the current zoom level. However, I would also like to choose the center point beforehand (current location of user). If circles are markers, and the square is my intended centerpoint, in the images below, the linked solution would create the first (left, top) image. I would like the second (right, bottom) image.

What I don't wantWhat I do want


Solution

  • You can create a LatLngBounds object and extend it with each of your markers coordinates. Then get your bounds object north east and south west coordinates and check whether theses coordinates are contained within the current map bounds. If not, zoom out and try again.

    Most of the below code is to generate random markers within certain bounds. The real interesting parts are where I call bounds.extend(position) and the fitAllBounds function.

    var map, bounds;
    
    function initialize() {
    
      var southWest = new google.maps.LatLng(40, -70);
      var northEast = new google.maps.LatLng(35, -80);
      var lngSpan = northEast.lng() - southWest.lng();
      var latSpan = northEast.lat() - southWest.lat();
    
      var center = new google.maps.LatLng(40, -70);
    
      map = new google.maps.Map(document.getElementById("map-canvas"), {
        zoom: 12,
        center: center,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      });
    
      // Add center marker
      new google.maps.Marker({
        position: center,
        label: 'C',
        map: map
      });
    
      // Create the bounds object
      bounds = new google.maps.LatLngBounds();
    
      // Create random markers
      for (var i = 0; i < 20; i++) {
    
        // Calculate a random position
        var position = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random());
    
        var marker = new google.maps.Marker({
          position: position,
          map: map
        });
    
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
          return function() {
            map.setZoom(5);
            map.setCenter(marker.position);
          }
        })(marker, i));
    
        // Extend the bounds with the last marker position
        bounds.extend(position);
      }
    
      // Fit all bounds once, when the map is ready
      google.maps.event.addListenerOnce(map, 'idle', function() {
    
        fitAllBounds(bounds);
      });
    }
    
    function fitAllBounds(b) {
    
      // Get north east and south west markers bounds coordinates
      var ne = b.getNorthEast();
      var sw = b.getSouthWest();
    
        // Get the current map bounds
      var mapBounds = map.getBounds();
    
      // Check if map bounds contains both north east and south west points
      if (mapBounds.contains(ne) && mapBounds.contains(sw)) {
    
        // Everything fits
        return;
    
      } else {
    
        var mapZoom = map.getZoom();
    
        if (mapZoom > 0) {
    
          // Zoom out
          map.setZoom(mapZoom - 1);
    
          // Try again
          fitAllBounds(b);
        }
      }
    }
    
    initialize();
    #map-canvas {
      height: 200px;
      width: 200px;
    }
    <div id="map-canvas"></div>
    
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>

    Here it is also on JSFiddle:

    JSFiddle demo