Reputation: 11193
I'm trying to set the boundaries so that they dont exceed the overlay image, however even though i have set them correctly to the imageBounds, it still seem to exceed the boundaries a bit. How can i calculate the correct bounds?
var currentMarker;
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.740, lng: -74.18},
zoom : 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
minZoom: 15,
maxZoom: 15
});
var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};
historicalOverlay = new google.maps.GroundOverlay(
'https://i.sstatic.net/0mgx2.jpg',
imageBounds);
historicalOverlay.setMap(map);
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.712216, -74.22655),
new google.maps.LatLng(40.773941, -74.12544)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'bounds_changed', function() {
if (strictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = strictBounds.getNorthEast().lng(),
maxY = strictBounds.getNorthEast().lat(),
minX = strictBounds.getSouthWest().lng(),
minY = strictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
#mapContainer {
height: 100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
position: relative;
}
#map {
height: 100%;
}
html, body {
height:100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
overflow:hidden;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<div id="mapContainer">
<div id="map"></div>
</div>
Upvotes: 0
Views: 434
Reputation: 161334
You need to calculate the bounds required to keep the edge of the browser viewport inside to the image bounds.
The new "strict" bounds is calculated to be the bounds of the image decreased by half the height of the viewport and half the width of the viewport on each side. It uses the fromLatLngToContainerPixel
and fromLatLngToContainerPixel
methods of the MapCanvasProjection class.
var windowWidth = window.innerWidth || d.documentElement.clientWidth || d.getElementsByTagName('body')[0].clientWidth;
var windowHeight = window.innerHeight || d.documentElement.clientHeight || d.getElementsByTagName('body')[0].clientHeight;
// calculate the new SW corner
var newSWpt = overlay.getProjection().fromLatLngToContainerPixel(strictBounds.getSouthWest());
newSWpt = new google.maps.Point((newSWpt.x + (windowWidth / 2)), (newSWpt.y - (windowHeight / 2)));
var newSW = overlay.getProjection().fromContainerPixelToLatLng(newSWpt);
// calculate the new NE corner
var newNEpt = overlay.getProjection().fromLatLngToContainerPixel(strictBounds.getNorthEast());
newNEpt = new google.maps.Point((newNEpt.x - (windowWidth / 2)), (newNEpt.y + (windowHeight / 2)));
var newNE = overlay.getProjection().fromContainerPixelToLatLng(newNEpt);
var newStrictBounds = new google.maps.LatLngBounds(newSW, newNE);
Note: there is some inertia to dragging, so the map can still be dragged slightly over the boundary, but it returns to the bounds.
code snippet:
var currentMarker;
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 40.740,
lng: -74.18
},
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
minZoom: 15,
maxZoom: 15
});
var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};
historicalOverlay = new google.maps.GroundOverlay(
'https://i.sstatic.net/0mgx2.jpg',
imageBounds);
historicalOverlay.setMap(map);
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(imageBounds.south, imageBounds.west),
new google.maps.LatLng(imageBounds.north, imageBounds.east)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'bounds_changed', function() {
var windowWidth = window.innerWidth || d.documentElement.clientWidth || d.getElementsByTagName('body')[0].clientWidth;
var windowHeight = window.innerHeight || d.documentElement.clientHeight || d.getElementsByTagName('body')[0].clientHeight;
var newSWpt = overlay.getProjection().fromLatLngToContainerPixel(strictBounds.getSouthWest());
newSWpt = new google.maps.Point((newSWpt.x + (windowWidth / 2)), (newSWpt.y - (windowHeight / 2)));
var newSW = overlay.getProjection().fromContainerPixelToLatLng(newSWpt);
var newNEpt = overlay.getProjection().fromLatLngToContainerPixel(strictBounds.getNorthEast());
newNEpt = new google.maps.Point((newNEpt.x - (windowWidth / 2)), (newNEpt.y + (windowHeight / 2)));
var newNE = overlay.getProjection().fromContainerPixelToLatLng(newNEpt);
var newStrictBounds = new google.maps.LatLngBounds(newSW, newNE);
if (newStrictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = newStrictBounds.getNorthEast().lng(),
maxY = newStrictBounds.getNorthEast().lat(),
minX = newStrictBounds.getSouthWest().lng(),
minY = newStrictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
#mapContainer {
height: 100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
position: relative;
}
#map {
height: 100%;
}
html,
body {
height: 100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
overflow: hidden;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<div id="mapContainer">
<div id="map"></div>
</div>
Upvotes: 1