whodeee whodeee - 1 month ago 19
Javascript Question

Update bounds based on zoom level for Google Maps API - Revised

I am building a custom map and setting bounds to the edge of it, but when the zoom level is changed the bounds don't seem to adhere to those edges. I have tried the solutions from this question but they seem to have the same issue.

You can see the same issue with this fiddle from @koen http://jsfiddle.net/koenpunt/n7h6t/, just pan to an edge and then zoom in a few times, the map will start to be cut off at the edges.

Here is my code:

var map;
window.onload = function() {

// Define our custom map type
var customMapType = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
var normalizedCoord = getNormalizedCoord(coord, zoom);
if(normalizedCoord && (normalizedCoord.x < Math.pow(2, zoom)) && (normalizedCoord.x > -1) && (normalizedCoord.y < Math.pow(2, zoom)) && (normalizedCoord.y > -1)) {
return zoom + '_' + normalizedCoord.x + '_' + normalizedCoord.y + '.jpg';
} else {
return 'empty.jpg';
}
},
tileSize: new google.maps.Size(256, 256),
maxZoom: 4,
name: 'Title'
});

// Basic options for our map
var myOptions = {
center: new google.maps.LatLng(0, 0),
zoom: 2,
minZoom: 2,
streetViewControl: false,
mapTypeControl: false,
mapTypeControlOptions: {
mapTypeIds: ["custom"]
}
};

// Init the map and hook our custom map type to it
map = new google.maps.Map(document.getElementById('map'), myOptions);
map.mapTypes.set('custom', customMapType);
map.setMapTypeId('custom');


// bounds of the desired area
var allowedBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-75.716, -90),
new google.maps.LatLng(75.716, 90)
);
var boundLimits = {
maxLat : allowedBounds.getNorthEast().lat(),
maxLng : allowedBounds.getNorthEast().lng(),
minLat : allowedBounds.getSouthWest().lat(),
minLng : allowedBounds.getSouthWest().lng()
};

var lastValidCenter = map.getCenter();
var newLat, newLng;
google.maps.event.addListener(map, 'center_changed', function() {
center = map.getCenter();
if (allowedBounds.contains(center)) {
// still within valid bounds, so save the last valid position
lastValidCenter = map.getCenter();
return;
}
newLat = lastValidCenter.lat();
newLng = lastValidCenter.lng();
if(center.lng() > boundLimits.minLng && center.lng() < boundLimits.maxLng){
newLng = center.lng();
}
if(center.lat() > boundLimits.minLat && center.lat() < boundLimits.maxLat){
newLat = center.lat();
}
map.panTo(new google.maps.LatLng(newLat, newLng));
});

//alert(map.getCenter());
}
function getBoundsM(){
alert(map.getBounds());
}


Edit: What I ended up doing was resizing the map smaller and added more background around the original map. This gave the impression that there was not a need to pan beyond the bounds of the searchable area. More of a 'smoke and mirrors' thing but it worked for my needs.

Answer

Your script forces the map's center to stay within a lat/lon boundary. It depends on the zoom level how much of the map around the center you see. If for a given zoom level the map spans 1000 km in longitude, the eastern-most point you're able to see is allowedBounds.getNorthEast().lng() + 500 km. If you zoom in and the spanned region reduces to 500 km, the eastern-most point becomes allowedBounds.getNorthEast().lng() + 250 km and so forth.

You seem to want to limit what a user is able to see, i.e. the locations of the map's boundary instead of its center. For this, you'll have to check whether map.getBounds().getNorthEast() and map.getBounds().getSouthWest() are within the allowed bounds.

Here is an updated JsFiddle which does that. Note that you can still zoom out to an area which is larger than the allowedBounds, but won't be able to move on that zoom level anymore: http://jsfiddle.net/Ya7ju/2/