Peter Pik
Peter Pik

Reputation: 11193

Setting pan Bounds in google maps equal to image overlay

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

Answers (1)

geocodezip
geocodezip

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

Related Questions