just__matt
just__matt

Reputation: 484

Google Maps API V3: Zoom out breaks pan limitation; workaround?

function initialize() {
    var latlng = new google.maps.LatLng(37.7702429, -122.4245789);

    var myOptions = {
      zoom: 3,
      center: latlng,
      disableDefaultUI: false,
      mapTypeId: google.maps.MapTypeId.TERRAIN,
    };

    var map = new google.maps.Map(document.getElementById("map_canvas"),
        myOptions);

    // Limit panning
    // Latitude bounds for map, longitude not important
    var southWest = new google.maps.LatLng(-85.000, -122.591);
    var northEast = new google.maps.LatLng(85.000, -122.333);
    var allowedBounds = new google.maps.LatLngBounds(southWest, northEast);

    // Add a move listener to restrict the bounds range
    google.maps.event.addListener(map, "center_changed", function() {checkBounds(); });

    //If zoom out at bound limit then map breaks; center doesn't change but bounds get broken. Listen for zoom event and try to correct bound break. **Doesn't Work**
    google.maps.event.addListener(map, 'zoom_changed', function() {checkBounds(); });

    // If the map position is out of range, move it back
    function checkBounds() {

      // Perform the check and return if OK
      if ((allowedBounds.getNorthEast().lat()>(map.getBounds().getNorthEast().lat()))&&(allowedBounds.getSouthWest().lat()<(map.getBounds().getSouthWest().lat()))) {
        lastValidCenter = map.getCenter();
        lastValidZoom = map.getZoom();
        return;
      }

      // not valid anymore => return to last valid position
      map.panTo(lastValidCenter);
      map.setZoom(lastValidZoom);
    }
  }

Basically I don't want the user to be able to see anything outside of the map, so I have restricted the latitudinal bounds. Works normally.

The issue is that if a user we to be viewing close to the bound limits and then zooms out so that the center doesn't change, but now the view-port bounds are outside of the bound limit, it does not correct and the map becomes unpannable.

Any help you geniuses can offer is mucho appreciated .

Upvotes: 1

Views: 2933

Answers (3)

john Ames
john Ames

Reputation: 11

don't try this on a working application or one thats in production make a new map somewhere local server different test program whatever.

PANING google maps has always been buggy especially around the edges or close to any of the google icons for pan zoom etc .

you need to get back to basics forget functions and scripting just ask simple IF statements

similar to this CAN'T REMEMBER WHAT I DONE A COUPLE OF YEARS AGO bit the gist is this.

1) store 4 variables to represent four lines on a map

left edge west right edge east top edge north bottom edge south

another to keep track of centre LAT LNG( the start centre same as first map displayed on load )

i,e if you pan left or west by X you make the centre / center (for americans) equal to current centre by plus the pan X ditto for all the other pan directions add or subtract the required latitudes and longitudes

test that you have not reached an edge (minus whatever by test trial and error) amount causes the google bug to appear close to icons around edge

or put another way make the LAT's and LNG's you are testing for to be smaller that the displayed map

if left or west edge of displayed map is at longitude x stop panning (by not doing anymore adjustments s to your centre VARIABLE at X - 10 longitudes same for all other 3 edges by plus or minus the required amount

top edge north will will at lattitude a bottom edge south will be at lattitude a - whatever you chose

left edge west will be at longitude b right edge east will be at longitude b- whatever you chose

they will all be within the displayed map but say 0.5 of a latitude or longitude than displayed map

if your pan crosses any of your fine lines set you centre var back or forward and you pan back or forward by say 0.1 to o.5 of a latitude or longitude viewers will just see a slight jerk back into place when they pan outside your pre de=fine four lines across the map.

Code will like like very basic learner code but it will work.

at least it did for me after some trial and error and the usual debugging typo errors etc.

taking this approach you are in control and not google scripts that may have undocumented code in them that causes the problems your experiencing because google cannot know what your trying to achieve only you know that.

SORRY HAVE NOT GOT THE CODE ANYMORE its not difficult just looks like newbie code and not the code advanced users prefer

it's like making a simple learner program where if you move up or down or diagonally you adjust centre LAT LNG in you var thats store current centre (this is your own variable not a google variable ) if centre (stored in your own variable ) crosses one of your lines stop panning and set Gmap center back forward up or down by a little thats plus or minus a fraction of a LAT or LNG

Upvotes: 1

just__matt
just__matt

Reputation: 484

Ok, so it was very simple. The zoom_changed event was not behaving as expected and bounds_changed on it's own was not satisfactory. This map will not go out of bounds by pan or zoom and is perfect for if you want the user to only see map and no grey background. Not so good if your users want to center the map at a high latitude and low zoom level. Cross that bridge later. Here's the code:

    // The allowed region which the whole map must be within
    var southWest = new google.maps.LatLng(-85.000, -122.591);
    var northEast = new google.maps.LatLng(85.000, -122.333);
    var allowedBounds = new google.maps.LatLngBounds(southWest, northEast);

    // Add listeners to trigger checkBounds(). bounds_changed deals with zoom changes.
    google.maps.event.addListener(map, "center_changed", function() {checkBounds(); });
    google.maps.event.addListener(map, 'bounds_changed', function() {checkBounds(); });

    // If the map bounds are out of range, move it back
    function checkBounds() {
      // Perform the check and return if OK
      if ((allowedBounds.getNorthEast().lat()>(map.getBounds().getNorthEast().lat()))&&(allowedBounds.getSouthWest().lat()<(map.getBounds().getSouthWest().lat()))) {
        lastValidCenter = map.getCenter();
        lastValidZoom = map.getZoom();
        return
      }
      // not valid anymore => return to last valid position
      map.panTo(lastValidCenter);
      map.setZoom(lastValidZoom);

Upvotes: 1

Tomas
Tomas

Reputation: 59485

Thanks, your script crashed my Mozilla :-) It is probably because the zoom_changed event doesn't give you correct center in getCenter() call. It is a known problem that zoom_changed event handler doesn't give correct bounds, so it may apply to the center too. I tried to modify your code to handle only the bounds_changed event (instead zoom_changed and center_changed), and the problem dissapeared! But it is not behaving ideally either. Maybe better look at this example of range limitation, it works quite nicely.

Upvotes: 0

Related Questions