Google Maps API V3 fitbounds() zooms out but never in

前端 未结 12 2375
感动是毒
感动是毒 2020-12-19 03:44

I\'ve created a quite complex store locator of sorts. The user enters their zip and a table returns results with corresponding markers on a map. They can page through result

相关标签:
12条回答
  • 2020-12-19 04:04

    The problem is this: we set

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

    so that we can later fit our markers to a bounded area on the map. GMaps will always zoom out asynchronously to fitBounds() accordingly, but will not zoom in to achieve the same (as previously noted by @broady). This is not ideal for many applications as once you have gone and displayed a series of markers on the map that caused the map to zoom out (maybe <10), it will not zoom back in without the user manually doing so.

    GMaps will continue to use the bounds of the (lack of better words) most zoomed out marker collection status (sorry). Setting to 'null' before each call for new markers gives you a fresh map to work with.

    To auto-zoom in, simply set the LatLngBounds(); to 'null' like so (see pseudo example below to see its placement):

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

    Pseudo example:

    // map stuff/initiation
    ...
    
    var bounds = new google.maps.LatLngBounds();
    var gmarkers = [];
    
    function CreateMarker (obj) {
        myLatLng = new google.maps.LatLng(obj['latitude'], obj['longitude']);
        marker = new google.maps.Marker({
            position: myLatLng,
            map: map
        });
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
                infowindow.setContent(obj['job']);
                infowindow.open(map, marker);
            }
        })(marker, i));
        bounds.extend(myLatLng);
        gmarkers.push(marker);
    }
    
    ....
    
    // here's an AJAX method I use to grab marker coords from a database:
    
    $.ajax({
        beforeSend: function() {
            clear_markers(gmarkers); // see below for clear_markers() function declaration
        },
        cache: false,
        data: params,
        dataType: 'json',
        timeout: 0,
        type: 'POST',
        url: '/map/get_markers.php?_=<?php echo md5(session_id() . time() . mt_rand(1,9999)); ?>',
        success: function(data) {
            if (data) {
                if (data['count'] > 0) {
                    var obj;
                    var results = data['results'];
    
                    // Plot the markers
                    for (r in results) {
                        if (r < (data['count'])) {
                            CreateMarker(results[r]);
                        }
                    }
                }
            }
        },
        complete: function() {
            map.fitBounds(bounds);
        }
    });
    
    // clear_markers()
    function clear_markers(a) {
        if (a) {
            for (i in a) {
                a[i].setMap(null);
            }
            a.length = 0;
        }
        bounds = new google.maps.LatLngBounds(null); // this is where the magic happens; setting LatLngBounds to null resets the current bounds and allows the new call for zoom in/out to be made directly against the latest markers to be plotted on the map
    }
    
    0 讨论(0)
  • 2020-12-19 04:04

    That's right, fitBounds only ensures that the provided bounds are visible. It doesn't zoom in to an appropriate level.

    You could first call setZoom(20), then fitBounds.

    0 讨论(0)
  • 2020-12-19 04:05

    Nothing fancy needed here. First fit bounds then pan to it. This will give you the proper zoom and contain the entire bounds.

    map.fitBounds(bounds);
    map.panToBounds(bounds);
    
    0 讨论(0)
  • 2020-12-19 04:05
    fitBounds: function(bounds, mapId)
        {
            //bounds: bounds, id: map id
            if (bounds==null) return false;
            maps[mapId].fitBounds(bounds);
        },  
    

    This should help, i use this method and works fine, on map v2 a little bit different way.

    0 讨论(0)
  • 2020-12-19 04:06

    Make sure there are no CSS animations on the width or height of your map. The animations interfere with the zoom behaviour of fitBound()

    I spent most of the day on this problem yesterday, and I encountered this StackOverflow post at least a dozen times. But I eventually had to find the problem the hard way on my own.

    Deleting the transition: all 0.5s ease; line below fixed it for me.

    .google-map {
      width: 100%;
      height: 0px;
      transition: all 0.5s ease;
    }
    
    .google-map.loaded {
        height: 400px;
    }
    
    
    0 讨论(0)
  • 2020-12-19 04:12

    I also had an issue with the map zooming way out when calling fitBounds a second time on the same map with new markers. This is the frankensolution that works for me:

    // This is a stationary point tho dynamic will work too
    
    var myLat = someLat,
        myLng = someLong;
    
    var map = false,
        markersArray = [];
    
    function makeOrderMap(lat, lng) { // pass in dynamic point when updating map
    
      var mapOptions = {
          center: new google.maps.LatLng(myLat, myLng),
          zoom: 16,
          mapTypeId: google.maps.MapTypeId.ROADMAP
      };
      deleteOverlays(); // remove any existing markers..
      if(!map) {  
        map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
      } 
    
      // Find the mid-point to center the map
    
      midLat = (parseFloat(lat) + parseFloat(myLat)) / 2;
      midLng = (parseFloat(lng) + parseFloat(myLng)) / 2;
      map.setCenter(new google.maps.LatLng(midLat, midLng));
      var newSpot = new google.maps.LatLng(lat, lng); 
    
      placeMarker(mapOptions.center);    
      placeMarker(newSpot);   
    
      // determine the distance between points for deciding the zoom level
    
      var dist = distHaversine(mapOptions.center, newSpot);
    
      var zoom = 10;
      if(dist < 1.25) {
        zoom = 15;
      } else if(dist < 2.5) {
        zoom = 14;
      } else if(dist < 5) {
        zoom = 13;
      } else if(dist < 10) {
        zoom = 12;
      } else if(dist < 20) {
        zoom = 11;
      }
      map.setZoom(zoom);  
    }
    
    
    rad = function(x) {return x*Math.PI/180;}
    
    distHaversine = function(p1, p2) {
      var R = 6371; // earth's mean radius in km
      var dLat  = rad(p2.lat() - p1.lat());
      var dLong = rad(p2.lng() - p1.lng());
    
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
    
      return d.toFixed(3);
    }
    
    function deleteOverlays() {
        if (markersArray) {
            for (i in markersArray) {
                markersArray[i].setMap(null);
            }
        markersArray = [];    
        markersArray.length = 0;
        }    
    }
    
    function placeMarker(location, alt_icon) {
    
        var marker = new google.maps.Marker({
            position: location, 
            map: map
          });
    
        // add marker in markers array
        markersArray.push(marker);
    }
    
    0 讨论(0)
提交回复
热议问题